diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 1bd460753c..de1ebdac1e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -22,7 +22,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: install GNU tools if: matrix.cfg.os == 'macos-12' @@ -33,6 +33,11 @@ jobs: - name: check-source.sh run: ../tools/check-source.sh + - name: update brew + if: matrix.cfg.os == 'macos-12' + run: | + brew update + - name: update-apt-cache if: matrix.cfg.os == 'ubuntu-22.04' run: sudo apt-get update @@ -41,7 +46,7 @@ jobs: if: matrix.cfg.os == 'ubuntu-22.04' run: sudo apt-get install latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended lmodern - - name: install (MacOS, Part 1/2) + - name: install (MacOS) if: matrix.cfg.os == 'macos-12' run: | brew install basictex @@ -50,9 +55,14 @@ jobs: sudo tlmgr update --self sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs extract layouts enumitem l3packages l3kernel imakeidx splitindex xstring - - name: make + - name: make (Linux) + if: matrix.cfg.os == 'ubuntu-22.04' run: make quiet + - name: make (MacOS) + if: matrix.cfg.os == 'macos-12' + run: make full + - name: check-output.sh run: ../tools/check-output.sh diff --git a/papers/n4945.html b/papers/n4945.html new file mode 100644 index 0000000000..e8335900cf --- /dev/null +++ b/papers/n4945.html @@ -0,0 +1,635 @@ + + + + + +N4945 + + +

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

+ +

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

+ + + +

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

+ + + +

Motions incorporated into working draft

+ +

Notes on motions

+ + + +

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

+ + + +

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..fd012dadb6 --- /dev/null +++ b/papers/n4945.md @@ -0,0 +1,488 @@ +# N4945 Editors' Report -- Programming Languages -- C++ + +Date: 2022-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/wd-index.md b/papers/wd-index.md index abd18efdb3..f81e361401 100644 --- a/papers/wd-index.md +++ b/papers/wd-index.md @@ -42,4 +42,5 @@ * [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/2022/n4928.pdf) 2022-11 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 diff --git a/source/algorithms.tex b/source/algorithms.tex index 61a5eb3713..ad8add5227 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -436,7 +436,7 @@ The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code -called from a \tcode{execution::unsequenced_policy} algorithm. +called from an \tcode{execution::unsequenced_policy} algorithm. \begin{note} Because \tcode{execution::unsequenced_policy} allows the execution of element access functions @@ -523,7 +523,7 @@ The behavior of a program is undefined if it invokes a vectorization-unsafe standard library function from user code -called from a \tcode{execution::parallel_unsequenced_policy} algorithm. +called from an \tcode{execution::parallel_unsequenced_policy} algorithm. \begin{note} Because \tcode{execution::parallel_unsequenced_policy} allows the execution of element access functions @@ -8398,6 +8398,8 @@ 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}). @@ -8505,8 +8507,10 @@ \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{Move\-Constructible} (\tref{cpp17.moveconstructible}) and +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and \oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. \pnum @@ -10763,21 +10767,13 @@ are destroyed in an unspecified order before allowing the exception to propagate. -\pnum -\begin{note} -When invoked on ranges of -potentially-overlapping subobjects\iref{intro.object}, -the algorithms specified in \ref{specialized.algorithms} -result in undefined behavior. -\end{note} - \pnum Some algorithms specified in \ref{specialized.algorithms} make use of the exposition-only function \tcode{\placeholdernc{voidify}}: \begin{codeblock} template constexpr void* @\placeholdernc{voidify}@(T& obj) noexcept { - return const_cast(static_cast(addressof(obj))); + return addressof(obj); } \end{codeblock} diff --git a/source/back.tex b/source/back.tex index 40954fd628..0ebe82f03b 100644 --- a/source/back.tex +++ b/source/back.tex @@ -18,40 +18,22 @@ \chapter{Bibliography} Programming languages, their environments, and system software interfaces --- Floating-point extensions for C --- Part 3: Interchange and extended types} % Other international standards. -\item - %%% Format for the following entry is based on that specified at - %%% http://www.iec.ch/standardsdev/resources/draftingpublications/directives/principles/referencing.htm - The Unicode Consortium. Unicode Standard Annex, \UAX{29}, - \doccite{Unicode Text Segmentation} [online]. - Edited by Mark Davis. Revision 35; issued for Unicode 12.0.0. 2019-02-15 [viewed 2020-02-23]. - Available from: \url{http://www.unicode.org/reports/tr29/tr29-35.html} -\item - The Unicode Consortium. Unicode Standard Annex, \UAX{31}, - \doccite{Unicode Identifier and Pattern Syntax} [online]. - Edited by Mark Davis. Revision 33; issued for Unicode 13.0.0. - 2020-02-13 [viewed 2021-06-08]. - Available from: \url{https://www.unicode.org/reports/tr31/tr31-33.html} -\item - The Unicode Standard Version 14.0, - \doccite{Core Specification}. - Unicode Consortium, ISBN 978-1-936213-29-0, copyright \copyright 2021 Unicode, Inc. - Available from: \url{https://www.unicode.org/versions/Unicode14.0.0/UnicodeStandard-14.0.pdf} \item IANA Time Zone Database. Available from: \url{https://www.iana.org/time-zones} % Literature references. \item Bjarne Stroustrup, - \doccite{The \Cpp{} Programming Language, second edition}, Chapter R. + \doccite{The \Cpp{} Programming Language, second edition}, Chapter R\@. Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright \copyright 1991 AT\&T \item - Brian W. Kernighan and Dennis M. Ritchie, - \doccite{The C Programming Language}, Appendix A. + 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 \item - P.J. Plauger, + P.J.\ Plauger, \doccite{The Draft Standard \Cpp{} Library}. - Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.J. Plauger + Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.J.\ Plauger \end{itemize} The arithmetic specification described in ISO/IEC 10967-1:2012 is diff --git a/source/basic.tex b/source/basic.tex index bd155ed606..0b6b3f78d0 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -680,6 +680,11 @@ 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 @@ -993,7 +998,7 @@ \begin{note} Overload resolution can consider potentially conflicting declarations found in multiple scopes -(e.g. via \grammarterm{using-directive}s or for operator functions), +(e.g., via \grammarterm{using-directive}s or for operator functions), in which case it is often ambiguous. \end{note} \begin{example} @@ -1083,10 +1088,12 @@ 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} or \grammarterm{opaque-enum-declaration} -is immediately after the \grammarterm{identifier} (if any) -in it\iref{dcl.enum}. +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 @@ -1512,18 +1519,18 @@ \pnum \indextext{scope!search}% -A \defn{search} in a scope $X$ for a name $N$ from a program point $P$ -is a single search in $X$ for $N$ from $P$ +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 $N$ is a \grammarterm{conversion-function-id} or +if $M$ is a \grammarterm{conversion-function-id} or if the single search would find nothing. \end{note} \pnum -The \defn{lookup set} for $N$ in $C$, called $S(N,C)$, +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}, @@ -1548,10 +1555,10 @@ 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 $T$ is incomplete, +If $C$ is incomplete, only base classes whose \grammarterm{base-specifier} appears before $P$ are considered. -If $T$ is an instantiated class, its base classes are not dependent. +If $C$ is an instantiated class, its base classes are not dependent. \end{note} \pnum @@ -1577,9 +1584,9 @@ \end{itemize} \pnum -The result of the search is the declaration set of $S(N,T)$. +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 $N$ +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} @@ -1602,7 +1609,7 @@ \end{example} \pnum -If $N$ is a non-dependent \grammarterm{conversion-function-id}, +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$ @@ -2622,8 +2629,11 @@ \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 exported, or + \item it is inline, or \item it was previously declared and the prior declaration did not have internal linkage; or \end{itemize} @@ -3329,7 +3339,7 @@ \pnum An operation that begins the lifetime of -an array of \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} +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. @@ -3407,8 +3417,11 @@ 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 and any program that -depends on the side effects produced by the destructor has undefined behavior. +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 diff --git a/source/classes.tex b/source/classes.tex index e13097d465..fcabddde7d 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -944,9 +944,10 @@ a member thereof, as described below. \pnum -When an \grammarterm{id-expression}\iref{expr.prim.id} that is not part of a -class member access syntax\iref{expr.ref} and not used to form a -pointer to member\iref{expr.unary.op} is used +When an \grammarterm{id-expression}\iref{expr.prim.id} that is +neither part of a class member access syntax\iref{expr.ref} +nor the unparenthesized operand of +the unary \tcode{\&} operator\iref{expr.unary.op} is used where the current class is \tcode{X}\iref{expr.prim.this}, if name lookup\iref{basic.lookup} resolves the name in the @@ -1221,6 +1222,9 @@ \pnum A constructor shall not be a coroutine. +\pnum +A constructor shall not have an explicit object parameter\iref{dcl.fct}. + \rSec3[class.default.ctor]{Default constructors} \pnum @@ -1944,7 +1948,7 @@ \end{example} \pnum -The implicitly-defined copy assignment operator for a +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} @@ -2095,7 +2099,7 @@ \pnum A defaulted destructor is a constexpr destructor -if it satisfies the requirements for a constexpr function\iref{dcl.constexpr}. +if it is constexpr-suitable\iref{dcl.constexpr}. \pnum Before a @@ -4270,6 +4274,19 @@ 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 \grammarterm{typedef-name}, only the accessibility of the typedef or alias declaration itself is considered. @@ -6542,7 +6559,8 @@ \begin{itemize} \item -If \tcode{a <=> b} is usable\iref{class.compare.default}, +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 diff --git a/source/compatibility.tex b/source/compatibility.tex index fbf61627fb..2bf0b9f233 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -189,6 +189,20 @@ } \end{codeblock} +\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{}. + \rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library} \diffref{format} @@ -231,6 +245,37 @@ std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"} \end{codeblock} +\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. +For example: +\begin{codeblock} +std::format("{:*^{}}", "", true); // ill-formed, previously returned \tcode{"*"} +std::format("{:*^{}}", "", '1'); // ill-formed, previously returned an + // implementation-defined number of \tcode{'*'} characters +\end{codeblock} + +\diffref{format.formatter.spec} +\change +Removed the \tcode{formatter} specialization: +\begin{codeblock} +template struct formatter; +\end{codeblock} +\rationale +The specialization is inconsistent with the design of \tcode{formatter}, +which is intended to be instantiated only with cv-unqualified object types. +\effect +Valid \CppXX{} code that instantiated the removed specialization +can become ill-formed. + \rSec2[diff.cpp20.strings]{\ref{strings}: strings library} \diffref{string.classes} @@ -277,6 +322,40 @@ }; \end{codeblock} +\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. +For example: +\begin{codeblock} +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} + \rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}} \rSec2[diff.cpp17.general]{General} diff --git a/source/config.tex b/source/config.tex index 0f2a0d13ee..a7e44b8931 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4928} -\newcommand{\prevdocno}{N4917} +\newcommand{\docno}{N4944} +\newcommand{\prevdocno}{N4928} \newcommand{\cppver}{202002L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index 7a15185cc8..0cd3b6ce60 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -497,7 +497,7 @@ \pnum \returns \tcode{distance(c.begin(), c.end())}, -i.e. the number of elements in the container. +i.e., the number of elements in the container. \pnum \complexity @@ -628,6 +628,14 @@ with value \tcode{a.end()} before the swap will have value \tcode{b.end()} after the swap. +\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}. + \rSec3[container.rev.reqmts]{Reversible container requirements} % Local command to index names as members of all containers. @@ -809,14 +817,6 @@ 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}. - \rSec3[container.opt.reqmts]{Optional container requirements} \pnum @@ -2008,6 +2008,12 @@ \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 @@ -4167,7 +4173,9 @@ \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 \tcode{(eq(r1, ke) \&\& eq(r1, r2)) == eq(r2, ke)}, + \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 @@ -4175,7 +4183,9 @@ \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 \tcode{(eq(r1, kx) \&\& eq(r1, r2)) == eq(r2, kx)}, and + \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} @@ -6139,7 +6149,7 @@ \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.requirements.general}. +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. @@ -8580,7 +8590,7 @@ 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.requirements.general}. +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} @@ -11496,7 +11506,6 @@ iterator find(const K& k); template const_iterator find(const K& k) const; - template size_type count(const key_type& k) const; template size_type count(const K& k) const; @@ -13177,6 +13186,13 @@ \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} @@ -13189,6 +13205,15 @@ defined in \ref{associative.general} may appear in deduction guides for container adaptors. +\pnum +The following exposition-only alias template +may appear in deduction guides for container adaptors: +\begin{codeblock} +template + using @\exposid{alloc-rebind}@ = // \expos + typename allocator_traits::template rebind_alloc; +\end{codeblock} + \rSec2[queue.syn]{Header \tcode{} synopsis} \indexheader{queue} @@ -14160,7 +14185,11 @@ \begin{itemdescr} \pnum \effects -Insert all elements of \tcode{rg} in \tcode{c}. +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 @@ -14727,15 +14756,24 @@ // \ref{flat.map.cons}, construct/copy/destroy flat_map() : flat_map(key_compare()) { } - flat_map(key_container_type key_cont, mapped_container_type mapped_cont); + flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); template flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); + template + flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); - flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont); + flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); template flat_map(sorted_unique_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); + template + flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); explicit flat_map(const key_compare& comp) : c(), compare(comp) { } @@ -14943,25 +14981,35 @@ }; }; - template - flat_map(KeyContainer, MappedContainer) + template> + flat_map(KeyContainer, MappedContainer, Compare = Compare()) -> flat_map, KeyContainer, MappedContainer>; + Compare, KeyContainer, MappedContainer>; 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) + template> + flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare = Compare()) -> flat_map, KeyContainer, MappedContainer>; + Compare, KeyContainer, MappedContainer>; 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()) @@ -14972,13 +15020,17 @@ -> flat_map<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; template>, - class Allocator> + class Allocator = allocator> flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) - -> flat_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare>; + -> 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}@>; + -> 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()) @@ -15005,15 +15057,17 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -flat_map(key_container_type key_cont, mapped_container_type mapped_cont); +flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and -\tcode{c.values} with \tcode{std::move(mapped_cont)}; -value-initializes \tcode{compare}; +Initializes +\tcode{c.keys} with \tcode{std::move(key_cont)}, +\tcode{c.values} with \tcode{std::move(mapped_cont)}, and +\tcode{compare} with \tcode{comp}; sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}; and finally erases the duplicate elements as if by: \begin{codeblock} @@ -15036,6 +15090,9 @@ template flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); +template + flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -15046,26 +15103,30 @@ \pnum \effects -Equivalent to \tcode{flat_map(key_cont, mapped_cont)}, +Equivalent to \tcode{flat_map(key_cont, mapped_cont)} and +\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively, except that \tcode{c.keys} and \tcode{c.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \pnum \complexity -Same as \tcode{flat_map(key_cont, mapped_cont)}. +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} -flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont); +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{c.keys} with \tcode{std::move(key_cont)} and -\tcode{c.values} with \tcode{std::move(mapped_cont)}; -value-initializes \tcode{compare}. +Initializes +\tcode{c.keys} with \tcode{std::move(key_cont)}, +\tcode{c.values} with \tcode{std::move(mapped_cont)}, and +\tcode{compare} with \tcode{comp}. \pnum \complexity @@ -15077,6 +15138,10 @@ template flat_map(sorted_unique_t s, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); +template + flat_map(sorted_unique_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -15087,7 +15152,8 @@ \pnum \effects -Equivalent to \tcode{flat_map(s, key_cont, mapped_cont)}, +Equivalent to \tcode{flat_map(s, key_cont, mapped_cont)} and +\tcode{flat_map(s, key_cont, \linebreak{}mapped_cont, comp)}, respectively, except that \tcode{c.keys} and \tcode{c.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -15870,16 +15936,25 @@ // \ref{flat.multimap.cons}, construct/copy/destroy flat_multimap() : flat_multimap(key_compare()) { } - flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont); + flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); template flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); + template + flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); flat_multimap(sorted_equivalent_t, - key_container_type key_cont, mapped_container_type mapped_cont); + key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); template flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); + template + flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); explicit flat_multimap(const key_compare& comp) : c(), compare(comp) { } @@ -16051,25 +16126,35 @@ key_compare compare; // \expos }; - template - flat_multimap(KeyContainer, MappedContainer) + template> + flat_multimap(KeyContainer, MappedContainer, Compare = Compare()) -> flat_multimap, KeyContainer, MappedContainer>; + Compare, KeyContainer, MappedContainer>; 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) + template> + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare()) -> flat_multimap, KeyContainer, MappedContainer>; + Compare, KeyContainer, MappedContainer>; 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()) @@ -16080,13 +16165,21 @@ -> flat_multimap<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; template>, - class Allocator> + class Allocator = allocator> flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) - -> flat_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare>; + -> 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}@>; + -> 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()) @@ -16114,15 +16207,17 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} -flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont); +flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and -\tcode{c.values} with \tcode{std::move(mapped_cont)}; -value-initializes \tcode{compare}; and +Initializes +\tcode{c.keys} with \tcode{std::move(key_cont)}, +\tcode{c.values} with \tcode{std::move(mapped_cont)}, and +\tcode{compare} with \tcode{comp}; sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}. \pnum @@ -16137,6 +16232,9 @@ template flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); +template + flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -16147,26 +16245,30 @@ \pnum \effects -Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)}, +Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)} and +\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively, except that \tcode{c.keys} and \tcode{c.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \pnum \complexity -Same as \tcode{flat_multimap(key_cont, mapped_cont)}. +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} -flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont); +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 \effects -Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and -\tcode{c.values} with \tcode{std::move(mapped_cont)}; -value-initializes \tcode{compare}. +Initializes +\tcode{c.keys} with \tcode{std::move(key_cont)}, +\tcode{c.values} with \tcode{std::move(mapped_cont)}, and +\tcode{compare} with \tcode{comp}. \pnum \complexity @@ -16178,6 +16280,10 @@ template flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Allocator& a); +template + flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -16188,7 +16294,8 @@ \pnum \effects -Equivalent to \tcode{flat_multimap(s, key_cont, mapped_cont)}, +Equivalent to \tcode{flat_multimap(s, key_cont, mapped_cont)} and +\tcode{flat_multimap(s, key_cont, mapped_cont, comp)}, respectively, except that \tcode{c.keys} and \tcode{c.val\-ues} are constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -16390,14 +16497,19 @@ // \ref{flat.set.cons}, constructors flat_set() : flat_set(key_compare()) { } - explicit flat_set(container_type cont); + explicit flat_set(container_type cont, const key_compare& comp = key_compare()); template flat_set(const container_type& cont, const Allocator& a); + template + flat_set(const container_type& cont, const key_compare& comp, const Allocator& a); - flat_set(sorted_unique_t, container_type cont) - : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(key_compare()) { } + flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare()) + : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } template flat_set(sorted_unique_t, const container_type& cont, const Allocator& a); + template + flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Allocator& a); explicit flat_set(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } @@ -16562,6 +16674,28 @@ key_compare @\exposid{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>; @@ -16571,13 +16705,17 @@ -> flat_set<@\placeholder{iter-value-type}@, Compare>; template>, - class Allocator = allocator>> + class Allocator = allocator>> flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) - -> flat_set, Compare>; + -> flat_set, Compare, + vector, + @\exposid{alloc-rebind}@>>>; - template - flat_set(from_range_t, R&&, Allocator) - -> flat_set, less>>; + template + flat_set(from_range_t, R&&, Allocator) + -> flat_set, less>, + vector, + @\exposid{alloc-rebind}@>>>; template> flat_set(initializer_list, Compare = Compare()) @@ -16597,14 +16735,14 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -explicit flat_set(container_type cont); +explicit flat_set(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \exposid{c} with \tcode{std::move(cont)}, -value-initializes \exposid{compare}, +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. @@ -16619,6 +16757,8 @@ \begin{itemdecl} template flat_set(const container_type& cont, const Allocator& a); +template + flat_set(const container_type& cont, const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -16628,19 +16768,23 @@ \pnum \effects -Equivalent to \tcode{flat_set(cont)}, +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 \complexity -Same as \tcode{flat_set(cont)}. +Same as \tcode{flat_set(cont)} and \tcode{flat_set(cont, comp)}, respectively. \end{itemdescr} \indexlibraryctor{flat_set}% \begin{itemdecl} template flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a); +template + flat_set(sorted_unique_t s, const container_type& cont, + const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -16650,7 +16794,8 @@ \pnum \effects -Equivalent to \tcode{flat_set(s, cont)}, +Equivalent to +\tcode{flat_set(s, cont)} and \tcode{flat_set(s, cont, comp)}, respectively, except that \exposid{c} is constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -16871,15 +17016,31 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{Key} meets the \oldconcept{MoveAssignable} requirements. + \pnum \effects -Equivalent to: -\begin{codeblock} -auto [erase_first, erase_last] = ranges::remove_if(c, pred); -auto n = erase_last - erase_first; -c.erase(erase_first, erase_last); -return n; -\end{codeblock} +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} \rSec2[flat.multiset]{Class template \tcode{flat_multiset}} @@ -16990,14 +17151,20 @@ // \ref{flat.multiset.cons}, constructors flat_multiset() : flat_multiset(key_compare()) { } - explicit flat_multiset(container_type cont); + explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); template flat_multiset(const container_type& cont, const Allocator& a); + template + flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a); - flat_multiset(sorted_equivalent_t, container_type cont) - : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(key_compare()) { } + flat_multiset(sorted_equivalent_t, container_type cont, + const key_compare& comp = key_compare()) + : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } template flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a); + template + flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Allocator& a); explicit flat_multiset(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } @@ -17164,6 +17331,28 @@ key_compare @\exposid{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}@, @\placeholder{iter-value-type}@, Compare>; @@ -17175,11 +17364,15 @@ template>, class Allocator = allocator>> flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) - -> flat_multiset, Compare>; + -> flat_multiset, Compare, + vector, + @\exposid{alloc-rebind}@>>>; - template - flat_multiset(from_range_t, R&&, Allocator) - -> flat_multiset, less>>; + template + flat_multiset(from_range_t, R&&, Allocator) + -> flat_multiset, less>, + vector, + @\exposid{alloc-rebind}@>>>; template> flat_multiset(initializer_list, Compare = Compare()) @@ -17199,14 +17392,14 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -explicit flat_multiset(container_type cont); +explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \exposid{c} with \tcode{std::move(cont)}, -value-initializes \exposid{compare}, and +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}. \pnum @@ -17219,6 +17412,8 @@ \begin{itemdecl} template flat_multiset(const container_type& cont, const Allocator& a); +template + flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -17228,19 +17423,24 @@ \pnum \effects -Equivalent to \tcode{flat_multiset(cont)}, +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 -Same as \tcode{flat_multiset(cont)}. +Same as \tcode{flat_multiset(cont)} and +\tcode{flat_multiset(cont, comp)}, respectively. \end{itemdescr} \indexlibraryctor{flat_multiset}% \begin{itemdecl} template flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a); +template + flat_multiset(sorted_equivalent_t s, const container_type& cont, + const key_compare& comp, const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -17250,7 +17450,8 @@ \pnum \effects -Equivalent to \tcode{flat_multiset(s, cont)}, +Equivalent to \tcode{flat_multiset(s, cont)} and +\tcode{flat_multiset(s, cont, comp)}, respectively, except that \exposid{c} is constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -17427,15 +17628,31 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{Key} meets the \oldconcept{MoveAssignable} requirements. + \pnum \effects -Equivalent to: -\begin{codeblock} -auto [erase_first, erase_last] = ranges::remove_if(c, pred); -auto n = erase_last - erase_first; -c.erase(erase_first, erase_last); -return n; -\end{codeblock} +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} \rSec2[container.adaptors.format]{Container adaptors formatting} @@ -17454,9 +17671,12 @@ template Container, class... U> struct formatter<@\placeholder{adaptor-type}@, charT> { private: - using @\exposid{maybe-const-adaptor}@ = // \expos - @\exposid{fmt-maybe-const}@<@\placeholder{adaptor-type}@, charT>; - formatter @\exposid{underlying_}@; // \expos + 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 @@ -18162,7 +18382,7 @@ whose reference type is \tcode{reference}. \pnum -All requirements on container iterators\iref{container.requirements} apply to +All requirements on container iterators\iref{container.reqmts} apply to \tcode{span::iterator} as well. \end{itemdescr} @@ -19130,6 +19350,12 @@ \tcode{layout_left::mapping} is a trivially copyable type that models \libconcept{regular} for each \tcode{E}. +\pnum +\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} \indexlibraryctor{layout_left::mapping}% @@ -19382,6 +19608,12 @@ \tcode{layout_right::mapping} is a trivially copyable type that models \libconcept{regular} for each \tcode{E}. +\pnum +\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}% @@ -19587,7 +19819,7 @@ public: // \ref{mdspan.layout.stride.cons}, constructors - constexpr mapping() noexcept = default; + constexpr mapping() noexcept; constexpr mapping(const mapping&) noexcept = default; template constexpr mapping(const extents_type&, span) noexcept; @@ -19636,6 +19868,12 @@ \tcode{layout_stride::mapping} is a trivially copyable type that models \libconcept{regular} for each \tcode{E}. +\pnum +\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 @@ -19699,6 +19937,25 @@ \rSec5[mdspan.layout.stride.cons]{Constructors} +\indexlibraryctor{layout_stride::mapping}% +\begin{itemdecl} +constexpr mapping() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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} + \indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} template diff --git a/source/declarations.tex b/source/declarations.tex index a63c317a72..e2e6054442 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -205,7 +205,7 @@ \pnum If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef} -specifier, the declaration is called a \defnx{typedef declaration}{declaration!typedef} +specifier, the declaration is a \defnx{typedef declaration}{declaration!typedef} and each \grammarterm{declarator-id} is declared to be a \grammarterm{typedef-name}, synonymous with its associated type\iref{dcl.typedef}. @@ -213,11 +213,20 @@ Such a \grammarterm{declarator-id} is an \grammarterm{identifier}\iref{class.conv.fct}. \end{note} -If the -\grammarterm{decl-specifier-seq} contains no \keyword{typedef} specifier, the -declaration is called a \defnx{function declaration}{declaration!function} if -the type associated with a \grammarterm{declarator-id} is a function type\iref{dcl.fct} and -an \defnx{object declaration}{declaration!object} otherwise. +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} +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} +\end{example} \pnum \indextext{definition!declaration as}% @@ -242,20 +251,38 @@ \end{note} \pnum -\indextext{\idxgram{static_assert}}% +\indextext{\idxcode{static_assert}}% In a \grammarterm{static_assert-declaration}, the \grammarterm{constant-expression} is contextually converted to \keyword{bool} and the converted expression shall be a constant expression\iref{expr.const}. 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 +so converted is \tcode{true} +or the expression is evaluated in the context of a template definition, +the declaration has no +effect. Otherwise, +the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed}, +the program is ill-formed, and the resulting diagnostic message\iref{intro.compliance} should include the text of the \grammarterm{string-literal}, 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} @@ -787,16 +814,17 @@ \pnum \indextext{specifier!\idxcode{constexpr}!function}% \indextext{constexpr function}% -The definition of a constexpr function shall satisfy the following -requirements: +A function is \defn{constexpr-suitable} if: \begin{itemize} \item -it shall not be a coroutine\iref{dcl.fct.def.coroutine}; +it is not a coroutine\iref{dcl.fct.def.coroutine}, and \item if the function is a constructor or destructor, -its class shall not have any virtual base classes. +its class does not have any virtual base classes. \end{itemize} +Except for instantiated constexpr functions, +non-templated constexpr functions shall be constexpr-suitable. \begin{example} \begin{codeblock} @@ -830,16 +858,6 @@ \end{codeblock} \end{example} -\pnum -If the instantiated template specialization of a constexpr function -template -or member function of a class template -would fail to satisfy the requirements for a constexpr -function, -that specialization is still a constexpr function, -even though a call to such a function cannot appear in a constant -expression. - \pnum An invocation of a constexpr function in a given context produces the same result as @@ -885,7 +903,9 @@ In any \keyword{constexpr} variable declaration, the full-expression of the initialization shall be a constant expression\iref{expr.const}. -A \keyword{constexpr} variable shall have constant destruction. +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} struct pixel { @@ -909,10 +929,12 @@ \pnum If a variable declared with the \keyword{constinit} specifier has -dynamic initialization\iref{basic.start.dynamic}, the program is ill-formed. +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\iref{basic.start.static}. +is initialized during static initialization. \end{note} \pnum @@ -1747,8 +1769,8 @@ \end{example} \pnum -Return type deduction for a templated entity -that is a function or 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. \begin{note} @@ -6252,7 +6274,7 @@ A function explicitly defaulted on its first declaration is implicitly inline\iref{dcl.inline}, and is implicitly constexpr\iref{dcl.constexpr} -if it satisfies the requirements for a constexpr function. +if it is constexpr-suitable. \pnum \begin{example} @@ -6300,7 +6322,7 @@ 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. A non-user-provided defaulted function -(i.e. implicitly declared or explicitly defaulted in the class) +(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}. \begin{note} @@ -6968,6 +6990,8 @@ 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 @@ -8251,7 +8275,7 @@ in determining the language linkage of class members, friend functions with a trailing \grammarterm{requires-clause}, and the -function type of class member functions. +function type of non-static class member functions. \begin{example} \begin{codeblock} extern "C" typedef void FUNC_c(); @@ -8505,6 +8529,17 @@ 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 diff --git a/source/diagnostics.tex b/source/diagnostics.tex index f1648bcb2d..a7ec160262 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -538,7 +538,6 @@ \indexlibraryglobal{ENETUNREACH}% \indexlibraryglobal{ENFILE}% \indexlibraryglobal{ENOBUFS}% -\indexlibraryglobal{ENODATA}% \indexlibraryglobal{ENODEV}% \indexlibraryglobal{ENOENT}% \indexlibraryglobal{ENOEXEC}% @@ -548,8 +547,6 @@ \indexlibraryglobal{ENOMSG}% \indexlibraryglobal{ENOPROTOOPT}% \indexlibraryglobal{ENOSPC}% -\indexlibraryglobal{ENOSR}% -\indexlibraryglobal{ENOSTR}% \indexlibraryglobal{ENOSYS}% \indexlibraryglobal{ENOTCONN}% \indexlibraryglobal{ENOTDIR}% @@ -571,7 +568,6 @@ \indexlibraryglobal{EROFS}% \indexlibraryglobal{ESPIPE}% \indexlibraryglobal{ESRCH}% -\indexlibraryglobal{ETIME}% \indexlibraryglobal{ETIMEDOUT}% \indexlibraryglobal{ETXTBSY}% \indexlibraryglobal{EWOULDBLOCK}% @@ -619,7 +615,6 @@ #define ENETUNREACH @\seebelow@ #define ENFILE @\seebelow@ #define ENOBUFS @\seebelow@ -#define ENODATA @\seebelow@ #define ENODEV @\seebelow@ #define ENOENT @\seebelow@ #define ENOEXEC @\seebelow@ @@ -629,8 +624,6 @@ #define ENOMSG @\seebelow@ #define ENOPROTOOPT @\seebelow@ #define ENOSPC @\seebelow@ -#define ENOSR @\seebelow@ -#define ENOSTR @\seebelow@ #define ENOSYS @\seebelow@ #define ENOTCONN @\seebelow@ #define ENOTDIR @\seebelow@ @@ -652,7 +645,6 @@ #define EROFS @\seebelow@ #define ESPIPE @\seebelow@ #define ESRCH @\seebelow@ -#define ETIME @\seebelow@ #define ETIMEDOUT @\seebelow@ #define ETXTBSY @\seebelow@ #define EWOULDBLOCK @\seebelow@ @@ -750,18 +742,15 @@ 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} @@ -779,7 +768,6 @@ 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} @@ -1756,6 +1744,10 @@ 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>; } @@ -2408,6 +2400,48 @@ Equivalent to: \tcode{return os << to_string(st);} \end{itemdescr} +\rSec3[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} + \rSec3[stacktrace.basic.hash]{Hash support} \begin{itemdecl} diff --git a/source/expressions.tex b/source/expressions.tex index 67edaeebf1..bd1c566664 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -321,7 +321,7 @@ that does not denote an object of type \cv{}~\keyword{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. +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} @@ -1142,38 +1142,34 @@ \item Otherwise, the expression is ill-formed. \end{itemize} -\item Otherwise, the integral promotions\iref{conv.prom} are -performed on both operands. +\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 the promoted operands: +Then the following rules are applied to determine \tcode{C}: \begin{itemize} -\item If both operands have the same type, no further conversion is -needed. +\item If \tcode{T1} and \tcode{T2} are the same type, \tcode{C} is that type. -\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 is converted to the type of the operand with -greater rank. +\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, 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 is 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 is converted -to the type of the operand with signed integer type. - -\item Otherwise, both operands are converted to the unsigned -integer type corresponding to the type of the operand with signed -integer type. +\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} @@ -1345,7 +1341,7 @@ \pnum An \grammarterm{id-expression} that denotes a non-static data member or -non-static member function of a class can only be used: +implicit object member function of a class can only be used: \begin{itemize} \item as part of a class member access\iref{expr.ref} in which the object expression @@ -1965,7 +1961,7 @@ the corresponding \grammarterm{lambda-expression}{'s} \grammarterm{parameter-declaration-clause} is followed by \keyword{constexpr} or \keyword{consteval}, or -it satisfies the requirements for a constexpr function\iref{dcl.constexpr}. +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}. @@ -2973,6 +2969,7 @@ 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} @@ -2991,8 +2988,6 @@ (including in the case where $n$ is zero). \end{example} \end{itemize} -\end{itemize} - \pnum \begin{example} \begin{codeblock} @@ -3055,18 +3050,6 @@ \end{codeblock} \tcode{D} is satisfied if \tcode{sizeof(decltype (+t)) == 1}\iref{temp.constr.atomic}. \end{example} - -\pnum -A local parameter shall only appear as an unevaluated operand\iref{term.unevaluated.operand} -within the \grammarterm{constraint-expression}. -\begin{example} -\begin{codeblock} -template concept C = requires (T a) { - requires sizeof(a) == 4; // OK - requires a == 0; // error: evaluation of a constraint variable -}; -\end{codeblock} -\end{example} \indextext{expression!requires|)} \indextext{expression!primary|)} @@ -3187,21 +3170,6 @@ conversion\iref{conv.func} is suppressed on the postfix expression), or have function pointer type. -\pnum -For a call to a non-static member function, -the postfix expression shall be an -implicit\iref{class.mfct.non.static,class.static} or explicit -class member access\iref{expr.ref} whose \grammarterm{id-expression} is a -function member name, or a pointer-to-member -expression\iref{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 \keyword{this}. -\begin{note} -A member function call of the form \tcode{f()} is interpreted as -\tcode{(*\keyword{this}).f()} (see~\ref{class.mfct.non.static}). -\end{note} - \pnum If the selected function is non-virtual, or if the \grammarterm{id-expression} in the class @@ -6555,6 +6523,11 @@ \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 or to unequal pointers to \tcode{void} +yields an unspecified result. +\end{note} \pnum If both operands (after conversions) are of arithmetic or enumeration type, each @@ -7262,7 +7235,7 @@ \pnum \begin{note} In contexts where the comma token is given special meaning -(e.g. function calls\iref{expr.call}, +(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}), @@ -7390,8 +7363,7 @@ \item an invocation of an instantiated constexpr function -that fails to satisfy the requirements -for a constexpr function; +that is not constexpr-suitable; \item an invocation of a virtual function\iref{class.virtual} @@ -7628,6 +7600,15 @@ to storage allocated with \tcode{std::allocator} or to an object whose lifetime began within the evaluation of $E$. +\pnum +For the purposes of determining whether $E$ is a core constant expression, +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 During the evaluation of an expression $E$ as a core constant expression, all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}} @@ -7785,6 +7766,11 @@ if the value is an object of class type, each non-static data member of reference type refers to an entity that is a permitted result of a constant expression, + + \item + if the value is an object of scalar type, + it does not have an indeterminate value\iref{basic.indet}, + \item if the value is of pointer type, it contains the address of an object with static storage duration, diff --git a/source/future.tex b/source/future.tex index 65a3c4ac6c..f417b2b506 100644 --- a/source/future.tex +++ b/source/future.tex @@ -188,12 +188,21 @@ It is possible that future versions of \Cpp{} will specify that these implicit definitions are deleted\iref{dcl.fct.def.delete}. +\rSec1[depr.lit]{Literal operator function declarations using an identifier} + +\pnum +A \grammarterm{literal-operator-id}\iref{over.literal} of the form +\begin{codeblock} +operator @\grammarterm{string-literal}@ @\grammarterm{identifier}@ +\end{codeblock} +is deprecated. + \rSec1[depr.template.template]{\tcode{template} keyword before qualified names} \pnum The use of the keyword \keyword{template} before the qualified name of a class or alias template -without a template argument list is deprecated. +without a template argument list is deprecated\iref{temp.names}. \rSec1[depr.res.on.required]{Requires paragraph} @@ -209,6 +218,67 @@ unless the function's \throws element specifies throwing an exception when the precondition is violated. +\rSec1[depr.numeric.limits.has.denorm]{\tcode{has_denorm} members in \tcode{numeric_limits}} + +\pnum +The following type is defined +in addition to those specified in \libheaderref{limits}: +\indexlibraryglobal{float_denorm_style}% +\begin{codeblock} +namespace std { + enum float_denorm_style { + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 + }; +} +\end{codeblock} + +\pnum +\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 +The values of \tcode{has_denorm} and \tcode{has_denorm_loss} of +specializations of \tcode{numeric_limits} are unspecified. + +\pnum +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 +The header \libheader{stdalign.h} has the following macro: +\indexheader{stdalign.h}% +\indexlibraryglobal{__alignas_is_defined}% +\begin{codeblock} +#define @\xname{alignas_is_defined}@ 1 +\end{codeblock} + +\pnum +The header \libheader{stdbool.h} has the following macro: +\indexheader{stdbool.h}% +\indexhdr{stdbool.h}% +\indexlibraryglobal{__bool_true_false_are_defined}% +\begin{codeblock} +#define @\xname{bool_true_false_are_defined}@ 1 +\end{codeblock} + \rSec1[depr.relops]{Relational operators}% \indexlibraryglobal{rel_ops}% @@ -1313,6 +1383,42 @@ \tcode{rdbuf()->pcount()}. \end{itemdescr} +\rSec1[depr.cerrno]{Deprecated error numbers} + +\pnum +The following macros are defined in addition to those +specified in \ref{cerrno.syn}: + +\indexlibraryglobal{ENODATA}% +\indexlibraryglobal{ENOSR}% +\indexlibraryglobal{ENOSTR}% +\indexlibraryglobal{ETIME}% +\begin{codeblock} +#define ENODATA @\seebelow@ +#define ENOSR @\seebelow@ +#define ENOSTR @\seebelow@ +#define ETIME @\seebelow@ +\end{codeblock} + +\pnum +The meaning of these macros is defined by the POSIX standard. + +\pnum +The following \tcode{enum errc} enumerators are defined +in addition to those specified in \ref{system.error.syn}: + +\begin{codeblock} +no_message_available, // \tcode{ENODATA} +no_stream_resources, // \tcode{ENOSR} +not_a_stream, // \tcode{ENOSTR} +stream_timeout, // \tcode{ETIME} +\end{codeblock} + +\pnum +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. + \rSec1[depr.default.allocator]{The default allocator} \pnum @@ -1364,7 +1470,6 @@ The header \libheaderrefx{type_traits}{meta.type.synop} has the following addition: -\indexlibraryglobal{is_literal_type}% \begin{codeblock} namespace std { template struct is_pod; @@ -2036,6 +2141,10 @@ If \tcode{(Mode \& little_endian)}, the facet shall generate a multibyte sequence in little-endian order, as opposed to the default big-endian order. +\item + UCS-2 is the same encoding as UTF-16, + except that it encodes scalar values in the range + \ucode{0000}--\ucode{ffff} (Basic Multilingual Plane) only. \end{itemize} \pnum @@ -2046,8 +2155,7 @@ \begin{itemize} \item The facet shall convert between UTF-8 multibyte sequences - and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}) - within the program. + and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}). \item Endianness shall not affect how multibyte sequences are read or written. \item @@ -2062,8 +2170,7 @@ \begin{itemize} \item The facet shall convert between UTF-16 multibyte sequences - and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}) - within the program. + and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}). \item Multibyte sequences shall be read or written according to the \tcode{Mode} flag, as set out above. @@ -2086,13 +2193,6 @@ The multibyte sequences may be written as either a text or a binary file. \end{itemize} -\pnum -The encoding forms UTF-8, UTF-16, and UTF-32 are specified in ISO/IEC 10646. -The encoding form UCS-2 is specified in ISO/IEC 10646:2003. -\begin{footnote} -Cancelled and replaced by ISO/IEC 10646:2017. -\end{footnote} - \rSec1[depr.conversions]{Deprecated convenience conversion interfaces} \rSec2[depr.conversions.general]{General} diff --git a/source/intro.tex b/source/intro.tex index e14bda23af..c247ada66b 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -51,14 +51,6 @@ Operating System Interface (POSIX), Technical Corrigendum 1} \item ISO/IEC/IEEE 9945:2009/Cor 2:2017, \doccite{Information Technology --- Portable Operating System Interface (POSIX), Technical Corrigendum 2} -\item ISO/IEC 10646, \doccite{Information technology --- -Universal Coded Character Set (UCS)} -\item ISO/IEC 10646:2003, -\begin{footnote} -Cancelled and replaced by ISO/IEC 10646:2017. -\end{footnote} -\doccite{Information technology --- -Universal Multiple-Octet Coded Character Set (UCS)} \item ISO/IEC/IEEE 60559:2020, \doccite{Information technology --- Microprocessor Systems --- Floating-Point arithmetic} \item ISO 80000-2:2009, \doccite{Quantities and units --- @@ -75,14 +67,8 @@ Language Specification}, Standard Ecma-262, third edition, 1999. \item -The Unicode Consortium. -Unicode Standard Annex, \UAX{44}, \doccite{Unicode Character Database}. -Edited by Ken Whistler and Lauren\c{t}iu Iancu. -Available from: \url{http://www.unicode.org/reports/tr44/} -\item -The Unicode Consortium. -The Unicode Standard, \doccite{Derived Core Properties}. -Available from: \url{https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt} +The Unicode Consortium. \doccite{The Unicode Standard}. +Available from: \url{https://www.unicode.org/versions/latest/} \end{itemize} \pnum @@ -104,12 +90,6 @@ hereinafter called \defn{ECMA-262}. \indextext{references!normative|)} -\pnum -\begin{note} -References to ISO/IEC 10646:2003 are used only -to support deprecated features\iref{depr.locale.stdcvt}. -\end{note} - \rSec0[intro.defs]{Terms and definitions} \pnum @@ -600,7 +580,7 @@ parameter-type-list, enclosing namespace, return type, -\grammarterm{template-head}, +signature of the \grammarterm{template-head}, and trailing \grammarterm{requires-clause} (if any) @@ -611,7 +591,7 @@ parameter-type-list, return type, enclosing class, -\grammarterm{template-head}, +signature of the \grammarterm{template-head}, and trailing \grammarterm{requires-clause} (if any) @@ -640,7 +620,7 @@ \cv-qualifiers (if any), \grammarterm{ref-qualifier} (if any), return type (if any), -\grammarterm{template-head}, +signature of the \grammarterm{template-head}, and trailing \grammarterm{requires-clause} (if any) @@ -649,6 +629,14 @@ \defncontext{class member function template specialization} signature of the member function template of which it is a specialization and its template arguments (whether explicitly specified or deduced) +\indexdefn{signature}% +\definition{signature}{defns.signature.template.head} +\defncontext{\grammarterm{template-head}} +template parameter list, +excluding template parameter names and default arguments, +and +\grammarterm{requires-clause} (if any) + \definition{stable algorithm}{defns.stable} \defncontext{library} \indexdefn{algorithm!stable}% @@ -792,16 +780,16 @@ \end{footnote} that program. \item +\indextext{behavior!undefined}% +If a program contains a violation of a rule for which no diagnostic is required, +this document places no requirement on implementations +with respect to that program. +\item \indextext{message!diagnostic}% -If a program contains a violation of any diagnosable rule or an occurrence +Otherwise, if a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as ``conditionally-supported'' when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message. -\item -\indextext{behavior!undefined}% -If a program contains a violation of a rule for which no diagnostic -is required, this document places no requirement on -implementations with respect to that program. \end{itemize} \begin{note} During template argument deduction and substitution, @@ -809,6 +797,20 @@ are treated differently; see~\ref{temp.deduct}. \end{note} +Furthermore, a conforming implementation +\begin{itemize} +\item +shall not accept a preprocessing translation unit containing +a \tcode{\#error} preprocessing directive\iref{cpp.error}, +\item +shall issue at least one diagnostic message for +each \tcode{\#warning} or \tcode{\#error} preprocessing directive +not following a \tcode{\#error} preprocessing directive in +a preprocessing translation unit, and +\item +shall not accept a translation unit with +a \grammarterm{static_assert-declaration} that fails\iref{dcl.pre}. +\end{itemize} \pnum \indextext{conformance requirements!library|(}% diff --git a/source/iostreams.tex b/source/iostreams.tex index c6851793ab..16a6d97b9a 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -27,7 +27,7 @@ \ref{iostreams.base} & Iostreams base classes & \tcode{} \\ \rowsep \ref{stream.buffers} & Stream buffers & \tcode{} \\ \rowsep \ref{iostream.format} & Formatting and manipulators & - \tcode{}, \tcode{}, \tcode{} \\ \rowsep + \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{string.streams} & String streams & \tcode{} \\ \rowsep \ref{span.streams} & Span-based streams & \tcode{} \\ \rowsep \ref{file.streams} & File streams & \tcode{} \\ \rowsep @@ -506,6 +506,17 @@ The results of including \libheader{iostream} in a translation unit shall be as if \libheader{iostream} defined an instance of \tcode{ios_base::Init} with static storage duration. +Each \Cpp{} library module\iref{std.modules} in a hosted implementation +shall behave as if it contains an interface unit that +defines an unexported \tcode{ios_base::Init} variable with +ordered initialization\iref{basic.start.dynamic}. + +\begin{note} +As a result, the definition of that variable is appearance-ordered before +any declaration following the point of importation of a \Cpp{} library module. +Whether such a definition exists is unobservable by a program that +does not reference any of the standard iostream objects. +\end{note} \pnum Mixing operations on corresponding wide- and narrow-character streams @@ -5819,7 +5830,7 @@ \effects Move constructs from the rvalue \tcode{rhs} by constructing the \tcode{basic_istream} base class with -\tcode{move(rhs)}. +\tcode{std::move(rhs)}. \end{itemdescr} \rSec4[iostream.dest]{Destructor} @@ -6850,7 +6861,7 @@ if invoking the native Unicode API requires transcoding, implementations should substitute invalid code units with \unicode{fffd}{replacement character} per -The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. \end{itemdescr} \rSec3[ostream.unformatted]{Unformatted output functions} @@ -7786,7 +7797,7 @@ If invoking the native Unicode API requires transcoding, implementations should substitute invalid code units with \unicode{fffd}{replacement character} per -The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. \end{itemdescr} \indexlibraryglobal{vprint_nonunicode}% @@ -12510,7 +12521,7 @@ ~basic_osyncstream(); // assignment - basic_osyncstream& operator=(basic_osyncstream&&) noexcept; + basic_osyncstream& operator=(basic_osyncstream&&); // \ref{syncstream.osyncstream.members}, member functions void emit(); @@ -12739,7 +12750,7 @@ \rSec3[fs.conform.9945]{POSIX conformance} \pnum -Some behavior is specified by reference to POSIX. How such behavior is actually implemented is unspecified. +Some behavior is specified by reference to POSIX\@. How such behavior is actually implemented is unspecified. \begin{note} This constitutes an ``as if'' rule allowing implementations to call native @@ -18515,15 +18526,15 @@ namespace std { using imaxdiv_t = @\seebelow@; - intmax_t imaxabs(intmax_t j); - imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); + constexpr intmax_t imaxabs(intmax_t j); + constexpr imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); intmax_t strtoimax(const char* nptr, char** endptr, int base); uintmax_t strtoumax(const char* nptr, char** endptr, int base); intmax_t wcstoimax(const wchar_t* nptr, wchar_t** endptr, int base); uintmax_t wcstoumax(const wchar_t* nptr, wchar_t** endptr, int base); - intmax_t abs(intmax_t); // optional, see below - imaxdiv_t div(intmax_t, intmax_t); // optional, see below + constexpr intmax_t abs(intmax_t); // optional, see below + constexpr imaxdiv_t div(intmax_t, intmax_t); // optional, see below } #define PRId@\placeholdernc{N}@ @\seebelow@ @@ -18592,15 +18603,19 @@ The header \libheader{cinttypes} includes the header \libheaderref{cstdint} instead of \libheader{stdint.h}, and \item +\tcode{intmax_t} and \tcode{uintmax_t} are not required +to be able to represent all values of extended integer types +wider than \tcode{long long} and \tcode{unsigned long long}, respectively, and +\item if and only if the type \tcode{intmax_t} designates an extended integer type\iref{basic.fundamental}, the following function signatures are added: \begin{codeblock} -intmax_t abs(intmax_t); -imaxdiv_t div(intmax_t, intmax_t); +constexpr intmax_t abs(intmax_t); +constexpr imaxdiv_t div(intmax_t, intmax_t); \end{codeblock} which shall have the same semantics as the function signatures -\tcode{intmax_t imaxabs(intmax_t)} and -\tcode{imaxdiv_t imaxdiv(intmax_t, intmax_t)}, respectively. +\tcode{constexpr intmax_t imaxabs(intmax_t)} and +\tcode{constexpr imaxdiv_t imaxdiv(intmax_t, intmax_t)}, respectively. \end{itemize} \xrefc{7.8} diff --git a/source/iterators.tex b/source/iterators.tex index 01768a7257..3b404f8c70 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -84,9 +84,12 @@ template concept indirectly_readable = @\seebelow@; // freestanding + template<@\libconcept{indirectly_readable}@ T> + using @\exposidnc{indirect-value-t}@ = @\seebelow@; // \expos + template<@\libconcept{indirectly_readable}@ T> using @\libglobal{iter_common_reference_t}@ = // freestanding - common_reference_t, iter_value_t&>; + common_reference_t, @\exposid{indirect-value-t}@>; // \ref{iterator.concept.writable}, concept \libconcept{indirectly_writable} template @@ -243,11 +246,11 @@ S bound); // \ref{range.iter.op.distance}, \tcode{ranges::distance} - template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> + template S> requires (!@\libconcept{sized_sentinel_for}@) constexpr iter_difference_t distance(I first, S last); // freestanding - template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> - constexpr iter_difference_t distance(const I& first, const S& last); // freestanding + template> S> + constexpr iter_difference_t> distance(I&& first, S last); // freestanding template<@\libconcept{range}@ R> constexpr range_difference_t distance(R&& r); // freestanding @@ -346,18 +349,21 @@ using const_sentinel = @\seebelow@; // freestanding // \ref{const.iterators.iterator}, class template \tcode{basic_const_iterator} - template + template<@\libconcept{input_iterator}@ Iterator> class basic_const_iterator; // freestanding template U> + requires @\libconcept{input_iterator}@> struct common_type, U> { // freestanding using type = basic_const_iterator>; }; template U> + requires @\libconcept{input_iterator}@> struct common_type> { // freestanding using type = basic_const_iterator>; }; template U> + requires @\libconcept{input_iterator}@> struct common_type, basic_const_iterator> { // freestanding using type = basic_const_iterator>; }; @@ -2408,6 +2414,21 @@ There are several concepts that group requirements of algorithms that take callable objects\iref{func.def} as arguments. +\rSec3[indirectcallable.traits]{Indirect callable traits} + +\pnum +To implement algorithms taking projections, +it is necessary to determine the projected type of an iterator's value type. +For the exposition-only alias template \exposid{indirect-value-t}, +\tcode{\exposid{indirect-value-t}} denotes +\begin{itemize} +\item +\tcode{invoke_result_t>} +if \tcode{T} names \tcode{projected}, and +\item +\tcode{iter_value_t\&} otherwise. +\end{itemize} + \rSec3[indirectcallable.indirectinvocable]{Indirect callables} \pnum @@ -2420,29 +2441,29 @@ concept @\deflibconcept{indirectly_unary_invocable}@ = @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{invocable}@&> && + @\libconcept{invocable}@> && @\libconcept{invocable}@> && @\libconcept{invocable}@> && @\libconcept{common_reference_with}@< - invoke_result_t&>, + invoke_result_t>, invoke_result_t>>; template concept @\deflibconcept{indirectly_regular_unary_invocable}@ = @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{regular_invocable}@&> && + @\libconcept{regular_invocable}@> && @\libconcept{regular_invocable}@> && @\libconcept{regular_invocable}@> && @\libconcept{common_reference_with}@< - invoke_result_t&>, + invoke_result_t>, invoke_result_t>>; template concept @\deflibconcept{indirect_unary_predicate}@ = @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{predicate}@&> && + @\libconcept{predicate}@> && @\libconcept{predicate}@> && @\libconcept{predicate}@>; @@ -2450,9 +2471,9 @@ concept @\deflibconcept{indirect_binary_predicate}@ = @\libconcept{indirectly_readable}@ && @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{predicate}@&, iter_value_t&> && - @\libconcept{predicate}@&, iter_reference_t> && - @\libconcept{predicate}@, iter_value_t&> && + @\libconcept{predicate}@, @\exposid{indirect-value-t}@> && + @\libconcept{predicate}@, iter_reference_t> && + @\libconcept{predicate}@, @\exposid{indirect-value-t}@> && @\libconcept{predicate}@, iter_reference_t> && @\libconcept{predicate}@, iter_common_reference_t>; @@ -2460,9 +2481,9 @@ concept @\deflibconcept{indirect_equivalence_relation}@ = @\libconcept{indirectly_readable}@ && @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{equivalence_relation}@&, iter_value_t&> && - @\libconcept{equivalence_relation}@&, iter_reference_t> && - @\libconcept{equivalence_relation}@, iter_value_t&> && + @\libconcept{equivalence_relation}@, @\exposid{indirect-value-t}@> && + @\libconcept{equivalence_relation}@, iter_reference_t> && + @\libconcept{equivalence_relation}@, @\exposid{indirect-value-t}@&> && @\libconcept{equivalence_relation}@, iter_reference_t> && @\libconcept{equivalence_relation}@, iter_common_reference_t>; @@ -2470,9 +2491,9 @@ concept @\deflibconcept{indirect_strict_weak_order}@ = @\libconcept{indirectly_readable}@ && @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && - @\libconcept{strict_weak_order}@&, iter_value_t&> && - @\libconcept{strict_weak_order}@&, iter_reference_t> && - @\libconcept{strict_weak_order}@, iter_value_t&> && + @\libconcept{strict_weak_order}@, @\exposid{indirect-value-t}@> && + @\libconcept{strict_weak_order}@, iter_reference_t> && + @\libconcept{strict_weak_order}@, @\exposid{indirect-value-t}@> && @\libconcept{strict_weak_order}@, iter_reference_t> && @\libconcept{strict_weak_order}@, iter_common_reference_t>; } @@ -2483,7 +2504,7 @@ \pnum Class template \tcode{projected} is used to constrain algorithms that accept callable objects and projections\iref{defns.projection}. -It combines a \libconcept{indirectly_readable} type \tcode{I} and +It combines an \libconcept{indirectly_readable} type \tcode{I} and a callable object type \tcode{Proj} into a new \libconcept{indirectly_readable} type whose \tcode{reference} type is the result of applying \tcode{Proj} to the \tcode{iter_reference_t} of \tcode{I}. @@ -2536,7 +2557,7 @@ \pnum The \libconcept{indirectly_movable} concept specifies the relationship between -a \libconcept{indirectly_readable} type and a \libconcept{indirectly_writable} type +an \libconcept{indirectly_readable} type and an \libconcept{indirectly_writable} type between which values may be moved. \begin{codeblock} @@ -2578,7 +2599,7 @@ \pnum The \libconcept{indirectly_copyable} concept specifies the relationship between -a \libconcept{indirectly_readable} type and a \libconcept{indirectly_writable} type +an \libconcept{indirectly_readable} type and an \libconcept{indirectly_writable} type between which values may be copied. \begin{codeblock} @@ -3028,7 +3049,7 @@ \rSec3[range.iter.op.distance]{\tcode{ranges::distance}} \indexlibraryglobal{distance}% \begin{itemdecl} -template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> +template S> requires (!@\libconcept{sized_sentinel_for}@) constexpr iter_difference_t ranges::distance(I first, S last); \end{itemdecl} @@ -3046,14 +3067,14 @@ \indexlibraryglobal{distance}% \begin{itemdecl} -template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> - constexpr iter_difference_t ranges::distance(const I& first, const S& last); +template> S> + constexpr iter_difference_t> ranges::distance(I&& first, S last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return last - first;} +Equivalent to: \tcode{return last - static_cast\&>(first);} \end{itemdescr} \indexlibraryglobal{distance}% @@ -3358,7 +3379,7 @@ \indexlibrarymember{base}{reverse_iterator}% \begin{itemdecl} -constexpr Iterator base() const; // explicit +constexpr Iterator base() const; \end{itemdecl} \begin{itemdescr} @@ -4211,12 +4232,18 @@ \begin{codeblock} namespace std { template - concept @\exposconcept{not-a-const-iterator}@ = @\seebelow@; + concept @\exposconcept{not-a-const-iterator}@ = @\seebelow@; // \expos + + template<@\libconcept{indirectly_readable}@ I> + using @\exposidnc{iter-const-rvalue-reference-t}@ = // \expos + common_reference_t&&, iter_rvalue_reference_t>; template<@\libconcept{input_iterator}@ Iterator> class @\libglobal{basic_const_iterator}@ { Iterator @\exposidnc{current_}@ = Iterator(); // \expos using @\exposidnc{reference}@ = iter_const_reference_t; // \expos + using @\exposidnc{rvalue-reference}@ = // \expos + @\exposid{iter-const-rvalue-reference-t}@; public: using iterator_concept = @\seebelow@; @@ -4236,7 +4263,7 @@ constexpr Iterator base() &&; constexpr @\exposid{reference}@ operator*() const; - constexpr const value_type* operator->() const + constexpr const auto* operator->() const requires is_lvalue_reference_v> && @\libconcept{same_as}@>, value_type>; @@ -4256,34 +4283,35 @@ requires @\libconcept{random_access_iterator}@; template<@\libconcept{sentinel_for}@ S> - friend constexpr bool operator==(const basic_const_iterator& x, const S& s); + constexpr bool operator==(const S& s) const; - friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) + constexpr bool operator<(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; - friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) + constexpr bool operator>(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; - friend constexpr bool operator<=(const basic_const_iterator& x, - const basic_const_iterator& y) + constexpr bool operator<=(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; - friend constexpr bool operator>=(const basic_const_iterator& x, - const basic_const_iterator& y) + constexpr bool operator>=(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; - friend constexpr auto operator<=>(const basic_const_iterator& x, - const basic_const_iterator& y) + constexpr auto operator<=>(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{three_way_comparable}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator<(const basic_const_iterator& x, const I& y) + constexpr bool operator<(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator>(const basic_const_iterator& x, const I& y) + constexpr bool operator>(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) + constexpr bool operator<=(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) + constexpr bool operator>=(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{different-from}@ I> + constexpr auto operator<=>(const I& y) const + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && + @\libconcept{three_way_comparable_with}@; template<@\exposconcept{not-a-const-iterator}@ I> friend constexpr bool operator<(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; @@ -4296,10 +4324,6 @@ template<@\exposconcept{not-a-const-iterator}@ I> friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; - template<@\exposconcept{different-from}@ I> - friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) - requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && - @\libconcept{three_way_comparable_with}@; friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n) @@ -4311,10 +4335,15 @@ difference_type n) requires @\libconcept{random_access_iterator}@; template<@\libconcept{sized_sentinel_for}@ S> - friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y); - template<@\libconcept{sized_sentinel_for}@ S> - requires @\exposconcept{different-from}@ + constexpr difference_type operator-(const S& y) const; + template<@\exposconcept{not-a-const-iterator}@ S> + requires @\libconcept{sized_sentinel_for}@ friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); + friend constexpr @\exposid{rvalue-reference}@ iter_move(const basic_const_iterator& i) + noexcept(noexcept(static_cast<@\exposid{rvalue-reference}@>(ranges::iter_move(i.@\exposid{current_}@)))) + { + return static_cast<@\exposid{rvalue-reference}@>(ranges::iter_move(i.@\exposid{current_}@)); + } }; } \end{codeblock} @@ -4427,7 +4456,7 @@ \indexlibrarymember{operator->}{basic_const_iterator}% \begin{itemdecl} -constexpr const value_type* operator->() const +constexpr const auto* operator->() const requires is_lvalue_reference_v> && @\libconcept{same_as}@>, value_type>; \end{itemdecl} @@ -4549,13 +4578,13 @@ \indexlibrarymember{operator==}{basic_const_iterator}% \begin{itemdecl} template<@\libconcept{sentinel_for}@ S> - friend constexpr bool operator==(const basic_const_iterator& x, const S& s); + constexpr bool operator==(const S& s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return x.\exposid{current_} == s;} +Equivalent to: \tcode{return \exposid{current_} == s;} \end{itemdescr} \indexlibrarymember{operator<}{basic_const_iterator}% @@ -4564,15 +4593,15 @@ \indexlibrarymember{operator>=}{basic_const_iterator}% \indexlibrarymember{operator<=>}{basic_const_iterator}% \begin{itemdecl} -friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) +constexpr bool operator<(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; -friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) +constexpr bool operator>(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; -friend constexpr bool operator<=(const basic_const_iterator& x, const basic_const_iterator& y) +constexpr bool operator<=(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; -friend constexpr bool operator>=(const basic_const_iterator& x, const basic_const_iterator& y) +constexpr bool operator>=(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@; -friend constexpr auto operator<=>(const basic_const_iterator& x, const basic_const_iterator& y) +constexpr auto operator<=>(const basic_const_iterator& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{three_way_comparable}@; \end{itemdecl} @@ -4583,7 +4612,7 @@ \pnum \effects Equivalent to: -\tcode{return x.\exposid{current_} \placeholder{op} \exposid{y.current_};} +\tcode{return \exposid{current_} \placeholder{op} \exposid{y.current_};} \end{itemdescr} \indexlibrarymember{operator<}{basic_const_iterator}% @@ -4593,19 +4622,19 @@ \indexlibrarymember{operator<=>}{basic_const_iterator}% \begin{itemdecl} template<@\exposconcept{different-from}@ I> - friend constexpr bool operator<(const basic_const_iterator& x, const I& y) + constexpr bool operator<(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator>(const basic_const_iterator& x, const I& y) + constexpr bool operator>(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) + constexpr bool operator<=(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) + constexpr bool operator>=(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; template<@\exposconcept{different-from}@ I> - friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) + constexpr auto operator<=>(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && @\libconcept{three_way_comparable_with}@; \end{itemdecl} @@ -4615,8 +4644,8 @@ Let \tcode{\placeholder{op}} be the operator. \pnum -\returns -Equivalent to: \tcode{return x.\exposid{current_} \placeholder{op} y;} +\effects +Equivalent to: \tcode{return \exposid{current_} \placeholder{op} y;} \end{itemdescr} \indexlibrarymember{operator<}{basic_const_iterator}% @@ -4675,19 +4704,19 @@ \indexlibrarymember{operator-}{basic_const_iterator}% \begin{itemdecl} template<@\libconcept{sized_sentinel_for}@ S> - friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y); + constexpr difference_type operator-(const S& y) const; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return x.\exposid{current_} - y;} +Equivalent to: \tcode{return \exposid{current_} - y;} \end{itemdescr} \indexlibrarymember{operator-}{basic_const_iterator}% \begin{itemdecl} -template<@\libconcept{sized_sentinel_for}@ S> - requires @\exposconcept{different-from}@ +template<@\exposconcept{not-a-const-iterator}@ S> + requires @\libconcept{sized_sentinel_for}@ friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); \end{itemdecl} @@ -5259,7 +5288,8 @@ @\libconcept{indirect_unary_predicate}@ Pred> requires @\libconcept{indirectly_movable}@ void move_if(I first, S last, O out, Pred pred) { - ranges::copy_if(move_iterator{first}, move_sentinel{last}, out, pred); + ranges::copy_if(move_iterator{std::move(first)}, move_sentinel{last}, + std::move(out), pred); } \end{codeblock} \end{example} @@ -7189,8 +7219,6 @@ \libheaderrefx{unordered_map}{unord.map.syn}, \libheaderrefx{unordered_set}{unord.set.syn}, and \libheaderref{vector}. -Each of these templates -is a designated customization point\iref{namespace.std}. \indexlibrary{\idxcode{begin(C\&)}}% \begin{itemdecl} diff --git a/source/lex.tex b/source/lex.tex index 0439a0de01..022a2ac9ad 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -33,7 +33,7 @@ and source files included\iref{cpp.include} via the preprocessing directive \tcode{\#include}, less any source lines skipped by any of the conditional inclusion\iref{cpp.cond} preprocessing directives, is -called a \defn{translation unit}. +called a \defnadj{preprocessing}{translation unit}. \begin{note} A \Cpp{} program need not all be translated at the same time. \end{note} @@ -80,8 +80,10 @@ \end{note} If an input file is determined to be a UTF-8 file, then it shall be a well-formed UTF-8 code unit sequence and -it is decoded to produce a sequence of UCS scalar values -that constitutes the sequence of elements of the translation character set. +it is decoded to produce a sequence of Unicode scalar values. +A sequence of translation character set elements is then formed +by mapping each Unicode scalar value +to the corresponding translation character set element. In the resulting sequence, each pair of characters in the input sequence consisting of \unicode{000d}{carriage return} followed by \unicode{000a}{line feed}, @@ -168,8 +170,10 @@ \item Whitespace characters separating tokens are no longer significant. Each preprocessing token is converted into a -token\iref{lex.token}. The resulting tokens are syntactically and -semantically analyzed and translated as a translation unit. +token\iref{lex.token}. The resulting tokens +constitute a \defn{translation unit} and +are syntactically and +semantically analyzed and translated. \begin{note} The process of analyzing and translating the tokens can occasionally result in one token being replaced by a sequence of other @@ -242,18 +246,17 @@ The \defnadj{translation}{character set} consists of the following elements: \begin{itemize} \item -each character named by ISO/IEC 10646, -as identified by its unique UCS scalar value, and +each abstract character assigned a code point in the Unicode codespace, and \item -a distinct character for each UCS scalar value -where no named character is assigned. +a distinct character for each Unicode scalar value +not assigned to an abstract character. \end{itemize} \begin{note} -ISO/IEC 10646 code points are integers +Unicode code points are integers in the range $[0, \mathrm{10FFFF}]$ (hexadecimal). A surrogate code point is a value in the range $[\mathrm{D800}, \mathrm{DFFF}]$ (hexadecimal). -A UCS scalar value is any code point that is not a surrogate code point. +A Unicode scalar value is any code point that is not a surrogate code point. \end{note} \pnum @@ -353,126 +356,27 @@ \tcode{\textbackslash U} \grammarterm{hex-quad} \grammarterm{hex-quad}, or \tcode{\textbackslash u\{\grammarterm{simple-hexadecimal-digit-sequence}\}} designates the character in the translation character set -whose UCS scalar value is the hexadecimal number represented by +whose Unicode scalar value is the hexadecimal number represented by the sequence of \grammarterm{hexadecimal-digit}s in the \grammarterm{universal-character-name}. -The program is ill-formed if that number is not a UCS scalar value. +The program is ill-formed if that number is not a Unicode scalar value. \pnum A \grammarterm{universal-character-name} that is a \grammarterm{named-universal-character} -designates the character named by its \grammarterm{n-char-sequence}. -A character is so named if the \grammarterm{n-char-sequence} is equal to -\begin{itemize} -\item -the associated character name or associated character name alias -specified in ISO/IEC 10646 subclause ``Code charts and lists of character names'' -or -\item -the control code alias given in \tref{lex.charset.ucn}. +designates the corresponding character +in the Unicode Standard (chapter 4.8 Name) +if the \grammarterm{n-char-sequence} is equal +to its character name or +to one of its character name aliases of +type ``control'', ``correction'', or ``alternate''; +otherwise, the program is ill-formed. \begin{note} -The aliases in \tref{lex.charset.ucn} are provided for control characters -which otherwise have no associated character name or character name alias. -These names are derived from +These aliases are listed in the Unicode Character Database's \tcode{NameAliases.txt}. -For historical reasons, control characters are formally unnamed. -\end{note} -\end{itemize} -\begin{note} -None of the associated character names, -associated character name aliases, or -control code aliases -have leading or trailing spaces. +None of these names or aliases have leading or trailing spaces. \end{note} -\begin{multicolfloattable}{Control code aliases}{lex.charset.ucn}{ll} -\unicode{0000}{null} \\ -\unicode{0001}{start of heading} \\ -\unicode{0002}{start of text} \\ -\unicode{0003}{end of text} \\ -\unicode{0004}{end of transmission} \\ -\unicode{0005}{enquiry} \\ -\unicode{0006}{acknowledge} \\ -\unicode{0007}{alert} \\ -\unicode{0008}{backspace} \\ -\unicode{0009}{character tabulation} \\ -\unicode{0009}{horizontal tabulation} \\ -\unicode{000a}{line feed} \\ -\unicode{000a}{new line} \\ -\unicode{000a}{end of line} \\ -\unicode{000b}{line tabulation} \\ -\unicode{000b}{vertical tabulation} \\ -\unicode{000c}{form feed} \\ -\unicode{000d}{carriage return} \\ -\unicode{000e}{shift out} \\ -\unicode{000e}{locking-shift one} \\ -\unicode{000f}{shift in} \\ -\unicode{000f}{locking-shift zero} \\ -\unicode{0010}{data link escape} \\ -\unicode{0011}{device control one} \\ -\unicode{0012}{device control two} \\ -\unicode{0013}{device control three} \\ -\unicode{0014}{device control four} \\ -\unicode{0015}{negative acknowledge} \\ -\unicode{0016}{synchronous idle} \\ -\unicode{0017}{end of transmission block} \\ -\unicode{0018}{cancel} \\ -\unicode{0019}{end of medium} \\ -\unicode{001a}{substitute} \\ -\unicode{001b}{escape} \\ -\unicode{001c}{information separator four} \\ -\unicode{001c}{file separator} \\ -\unicode{001d}{information separator three} \\ -\unicode{001d}{group separator} \\ -\unicode{001e}{information separator two} \\ -\unicode{001e}{record separator} \\ -\unicode{001f}{information separator one} \\ -\unicode{001f}{unit separator} \\ -\columnbreak -\unicode{007f}{delete} \\ -\unicode{0082}{break permitted here} \\ -\unicode{0083}{no break here} \\ -\unicode{0084}{index} \\ -\unicode{0085}{next line} \\ -\unicode{0086}{start of selected area} \\ -\unicode{0087}{end of selected area} \\ -\unicode{0088}{character tabulation set} \\ -\unicode{0088}{horizontal tabulation set} \\ -\unicode{0089}{character tabulation with justification} \\ -\unicode{0089}{horizontal tabulation with justification} \\ -\unicode{008a}{line tabulation set} \\ -\unicode{008a}{vertical tabulation set} \\ -\unicode{008b}{partial line forward} \\ -\unicode{008b}{partial line down} \\ -\unicode{008c}{partial line backward} \\ -\unicode{008c}{partial line up} \\ -\unicode{008d}{reverse line feed} \\ -\unicode{008d}{reverse index} \\ -\unicode{008e}{single shift two} \\ -\unicode{008e}{single-shift-2} \\ -\unicode{008f}{single shift three} \\ -\unicode{008f}{single-shift-3} \\ -\unicode{0090}{device control string} \\ -\unicode{0091}{private use one} \\ -\unicode{0091}{private use-1} \\ -\unicode{0092}{private use two} \\ -\unicode{0092}{private use-2} \\ -\unicode{0093}{set transmit state} \\ -\unicode{0094}{cancel character} \\ -\unicode{0095}{message waiting} \\ -\unicode{0096}{start of guarded area} \\ -\unicode{0096}{start of protected area} \\ -\unicode{0097}{end of guarded area} \\ -\unicode{0097}{end of protected area} \\ -\unicode{0098}{start of string} \\ -\unicode{009a}{single character introducer} \\ -\unicode{009b}{control sequence introducer} \\ -\unicode{009c}{string terminator} \\ -\unicode{009d}{operating system command} \\ -\unicode{009e}{privacy message} \\ -\unicode{009f}{application program command} \\ -\end{multicolfloattable} - \pnum If a \grammarterm{universal-character-name} outside the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or @@ -491,10 +395,6 @@ The \defnadj{basic literal}{character set} consists of all characters of the basic character set, plus the control characters specified in \tref{lex.charset.literal}. -\begin{note} -The alias \uname{bell} for \ucode{0007} shown in ISO 10646 -is ambiguous with \unicode{1f514}{bell}. -\end{note} \begin{floattable}{Additional control characters in the basic literal character set}{lex.charset.literal}{ll} \topline @@ -544,9 +444,10 @@ \indextext{UTF-16}% \indextext{UTF-32}% For a UTF-8, UTF-16, or UTF-32 literal, -the UCS scalar value +the Unicode scalar value corresponding to each character of the translation character set -is encoded as specified in ISO/IEC 10646 for the respective UCS encoding form. +is encoded as specified in the Unicode Standard +for the respective Unicode encoding form. \indextext{character set|)} \rSec1[lex.pptoken]{Preprocessing tokens} @@ -887,14 +788,14 @@ \begin{bnf} \nontermdef{identifier-start}\br nondigit\br - \textnormal{an element of the translation character set of class XID_Start} + \textnormal{an element of the translation character set with the Unicode property XID_Start} \end{bnf} \begin{bnf} \nontermdef{identifier-continue}\br digit\br nondigit\br - \textnormal{an element of the translation character set of class XID_Continue} + \textnormal{an element of the translation character set with the Unicode property XID_Continue} \end{bnf} \begin{bnf} @@ -913,8 +814,9 @@ \pnum \indextext{name!length of}% \indextext{name}% -The character classes XID_Start and XID_Continue -are Derived Core Properties as described by \UAX{44}. +\begin{note} +The character properties XID_Start and XID_Continue are Derived Core Properties +as described by \UAX{44} of the Unicode Standard. \begin{footnote} On systems in which linkers cannot accept extended characters, an encoding of the \grammarterm{universal-character-name} can be used in @@ -925,9 +827,10 @@ place a translation limit on significant characters for external identifiers. \end{footnote} +\end{note} The program is ill-formed if an \grammarterm{identifier} does not conform to -Normalization Form C as specified in ISO/IEC 10646. +Normalization Form C as specified in the Unicode Standard. \begin{note} Identifiers are case-sensitive. \end{note} @@ -966,7 +869,9 @@ \indextext{\idxcode{_}|see{character, underscore}}% \indextext{character!underscore!in identifier}% \indextext{reserved identifier}% -In addition, some identifiers are reserved for use by \Cpp{} +In addition, some identifiers +appearing as a \grammarterm{token} or \grammarterm{preprocessing-token} +are reserved for use by \Cpp{} implementations and shall not be used otherwise; no diagnostic is required. \begin{itemize} @@ -1498,8 +1403,7 @@ \begin{bnf} \nontermdef{hexadecimal-escape-sequence}\br - \terminal{\textbackslash x} hexadecimal-digit\br - hexadecimal-escape-sequence hexadecimal-digit\br + \terminal{\textbackslash x} simple-hexadecimal-digit-sequence\br \terminal{\textbackslash x\{} simple-hexadecimal-digit-sequence \terminal{\}} \end{bnf} @@ -1541,7 +1445,7 @@ \pnum The kind of a \grammarterm{character-literal}, -its type, and its associated character encoding +its type, and its associated character encoding\iref{lex.charset} are determined by its \grammarterm{encoding-prefix} and its \grammarterm{c-char-sequence} as defined by \tref{lex.ccon.literal}. @@ -1902,7 +1806,7 @@ \indextext{type!\idxcode{char32_t}}% The kind of a \grammarterm{string-literal}, its type, and -its associated character encoding +its associated character encoding\iref{lex.charset} are determined by its encoding prefix and sequence of \grammarterm{s-char}s or \grammarterm{r-char}s as defined by \tref{lex.string.literal} @@ -2099,7 +2003,7 @@ \impldef{code unit sequence for non-representable \grammarterm{string-literal}} code unit sequence is encoded. \begin{note} -No character lacks representation in any of the UCS encoding forms. +No character lacks representation in any Unicode encoding form. \end{note} When encoding a stateful character encoding, implementations should encode the first such sequence @@ -2256,19 +2160,19 @@ parameter type \tcode{unsigned long long}, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@(@\placeholder{n}@ULL) +operator ""@\placeholder{X}@(@\placeholder{n}@ULL) \end{codeblock} Otherwise, \placeholder{S} shall contain a raw literal operator or a numeric literal operator template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@("@\placeholder{n}@") +operator ""@\placeholder{X}@("@\placeholder{n}@") \end{codeblock} Otherwise (\placeholder{S} contains a numeric literal operator template), \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() +operator ""@\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() \end{codeblock} where \placeholder{n} is the source character sequence $c_1c_2...c_k$. \begin{note} @@ -2282,19 +2186,19 @@ with parameter type \tcode{long double}, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@(@\placeholder{f}@L) +operator ""@\placeholder{X}@(@\placeholder{f}@L) \end{codeblock} Otherwise, \placeholder{S} shall contain a raw literal operator or a numeric literal operator template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator, the \grammarterm{literal} \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@("@\placeholder{f}@") +operator ""@\placeholder{X}@("@\placeholder{f}@") \end{codeblock} Otherwise (\placeholder{S} contains a numeric literal operator template), \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() +operator ""@\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() \end{codeblock} where \placeholder{f} is the source character sequence $c_1c_2...c_k$. \begin{note} @@ -2312,11 +2216,11 @@ a well-formed \grammarterm{template-argument}, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@<@\placeholder{str}{}@>() +operator ""@\placeholder{X}@<@\placeholder{str}{}@>() \end{codeblock} Otherwise, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@(@\placeholder{str}{}@, @\placeholder{len}{}@) +operator ""@\placeholder{X}@(@\placeholder{str}{}@, @\placeholder{len}{}@) \end{codeblock} \pnum @@ -2327,19 +2231,19 @@ literal \placeholder{L} is treated as a call of the form \begin{codeblock} -operator "" @\placeholder{X}@(@\placeholder{ch}{}@) +operator ""@\placeholder{X}@(@\placeholder{ch}{}@) \end{codeblock} \pnum \begin{example} \begin{codeblock} -long double operator "" _w(long double); -std::string operator "" _w(const char16_t*, std::size_t); -unsigned operator "" _w(const char*); +long double operator ""_w(long double); +std::string operator ""_w(const char16_t*, std::size_t); +unsigned operator ""_w(const char*); int main() { - 1.2_w; // calls \tcode{operator "" _w(1.2L)} - u"one"_w; // calls \tcode{operator "" _w(u"one", 3)} - 12_w; // calls \tcode{operator "" _w("12")} + 1.2_w; // calls \tcode{operator ""_w(1.2L)} + u"one"_w; // calls \tcode{operator ""_w(u"one", 3)} + 12_w; // calls \tcode{operator ""_w("12")} "two"_w; // error: no applicable literal operator } \end{codeblock} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 266d411852..e64f55a063 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -121,7 +121,7 @@ The regular expressions library\iref{re} provides regular expression matching and searching. \pnum -The thread support library\iref{thread} provides components to create +The concurrency support library\iref{thread} provides components to create and manage threads, including atomic operations, mutual exclusion, and interthread communication. @@ -1471,15 +1471,6 @@ the freestanding items\iref{freestanding.item} declared in the header. \indextext{implementation!freestanding|)}% -\pnum -\begin{note} -Throwing a standard library provided exception -is not observably different from \tcode{terminate()} -if the implementation does not -unwind the stack during exception handling\iref{except.handle} and -the user's program contains no catch blocks. -\end{note} - \rSec2[using]{Using the library} \rSec3[using.overview]{Overview} @@ -2018,9 +2009,10 @@ given type or expression is specified. Within the standard library \tcode{allocator_traits} template, an optional requirement that is not supplied by an allocator is -replaced by the specified default type or expression. A user specialization of -\tcode{allocator_traits} may provide different defaults and may provide -defaults for different requirements than the primary template. +replaced by the specified default type or expression. +\begin{note} +There are no program-defined specializations of \tcode{allocator_traits}. +\end{note} \begin{itemdecl} typename X::pointer @@ -2327,11 +2319,11 @@ \begin{itemdescr} \pnum \result -\tcode{allocation_result} +\tcode{allocation_result} \pnum \returns -\tcode{allocation_result\{ptr, count\}} +\tcode{allocation_result\{ptr, count\}} where \tcode{ptr} is memory allocated for an array of \tcode{count} \tcode{T} and such an object is created but array elements are not constructed, such that $\tcode{count} \geq \tcode{n}$. @@ -2343,10 +2335,7 @@ \pnum \remarks -An allocator need not support \tcode{allocate_at_least}, -but no default is provided in \tcode{allocator_traits}. -If an allocator has an \tcode{allocate_at_least} member, -it shall satisfy the requirements. +Default: \tcode{\{a.allocate(n), n\}}. \end{itemdescr} \begin{itemdecl} @@ -2748,10 +2737,10 @@ template SimpleAllocator(const SimpleAllocator& other); - [[nodiscard]] T* allocate(std::size_t n); + T* allocate(std::size_t n); void deallocate(T* p, std::size_t n); - bool operator==(const SimpleAllocator&) const; + template bool operator==(const SimpleAllocator& rhs) const; }; \end{codeblock} \end{example} @@ -2872,53 +2861,6 @@ either a standard library non-static member function\iref{member.functions} or an instantiation of a standard library member function template. -\pnum -Other than in namespace \tcode{std} -or in a namespace -within namespace \tcode{std}, -a program may provide -an overload for any library function template -designated as a \defn{customization point}, -provided that -(a) -the overload's declaration depends -on at least one user-defined type -and -(b) -the overload meets the standard library requirements -for the customization point. -\begin{footnote} -Any library customization point -must be prepared -to work adequately -with any user-defined overload -that meets the minimum requirements -of this document. -Therefore -an implementation can elect, -under the as-if rule\iref{intro.execution}, -to provide any customization point -in the form -of an instantiated function object\iref{function.objects} -even though the customization point's specification -is in the form -of a function template. -The template parameters -of each such function object -and the function parameters -and return type -of the object's \tcode{operator()} -must match those -of the corresponding customization point's specification. -\end{footnote} -\begin{note} -This permits -a (qualified or unqualified) call -to the customization point -to invoke the most appropriate overload -for the given arguments. -\end{note} - \pnum A translation unit shall not declare namespace \tcode{std} to be an inline namespace\iref{namespace.def}. @@ -3154,6 +3096,10 @@ \pnum Literal suffix identifiers\iref{over.literal} that do not start with an underscore are reserved for future standardization. +Literal suffix identifiers that contain a double underscore +\tcode{\unun} +\indextext{character!underscore}% +are reserved for use by \Cpp{} implementations. \rSec3[alt.headers]{Headers} diff --git a/source/locales.tex b/source/locales.tex index 788abc1be0..4b6e0376e0 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -555,15 +555,19 @@ \begin{itemdescr} \pnum \effects -The same as \tcode{locale(std_name.c_str())}. +Equivalent to \tcode{locale(std_name.c_str())}. \end{itemdescr} \indexlibraryctor{locale}% \begin{itemdecl} -locale(const locale& other, const char* std_name, category); +locale(const locale& other, const char* std_name, category cats); \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{cats} is a valid \tcode{category} value\iref{locale.category}. + \pnum \effects Constructs a locale as a copy of \tcode{other} @@ -572,7 +576,7 @@ \pnum \throws -\tcode{runtime_error} if the argument is not valid, or is null. +\tcode{runtime_error} if the second argument is not valid, or is null. \pnum \remarks @@ -581,13 +585,13 @@ \indexlibraryctor{locale}% \begin{itemdecl} -locale(const locale& other, const string& std_name, category cat); +locale(const locale& other, const string& std_name, category cats); \end{itemdecl} \begin{itemdescr} \pnum \effects -The same as \tcode{locale(other, std_name.c_str(), cat)}. +Equivalent to \tcode{locale(other, std_name.c_str(), cats)}. \end{itemdescr} \indexlibraryctor{locale}% @@ -605,7 +609,9 @@ \pnum \remarks -The resulting locale has no name. +If \tcode{f} is null, +the resulting locale has the same name as \tcode{other}. +Otherwise, the resulting locale has no name. \end{itemdescr} \indexlibraryctor{locale}% @@ -614,6 +620,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{cats} is a valid \tcode{category} value. + \pnum \effects Constructs a locale incorporating all facets from the first argument @@ -622,8 +632,10 @@ \pnum \remarks -The resulting locale has a name if and only if -the first two arguments have names. +If \tcode{cats} is equal to \tcode{locale::none}, +the resulting locale has a name if and only if the first argument has a name. +Otherwise, the resulting locale has a name if and only if +the first two arguments both have names. \end{itemdescr} \indexlibrarymember{operator=}{locale}% diff --git a/source/macros.tex b/source/macros.tex index 2bf9d28192..a615cfabb0 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -253,6 +253,13 @@ % Usage: \defnadjx{scalar}{types}{type} \newcommand{\defnadjx}[3]{\indextext{#1 #3|see{#3, #1}}\indexdefn{#3!#1}\textit{#1 #2}} +% Macros used for the grammar of std::format format specifications. +% FIXME: For now, keep the format grammar productions out of the index, since +% they conflict with the main grammar. +% Consider renaming these en masse (to fmt-* ?) to avoid this problem. +\newcommand{\fmtnontermdef}[1]{{\BnfNontermshape#1\itcorr}\textnormal{:}} +\newcommand{\fmtgrammarterm}[1]{\gterm{#1}} + %%-------------------------------------------------- %% allow line break if needed for justification %%-------------------------------------------------- diff --git a/source/memory.tex b/source/memory.tex index 8419e02b91..4b01ba4006 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -141,6 +141,9 @@ template constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding const pair&& pr) noexcept; + template + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding + P&& p) noexcept; template constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding U&& u) noexcept; @@ -153,16 +156,12 @@ // \ref{allocator.traits}, allocator traits template struct allocator_traits; // freestanding - template + template struct allocation_result { // freestanding Pointer ptr; - size_t count; + SizeType count; }; - template - [[nodiscard]] constexpr allocation_result::pointer> - allocate_at_least(Allocator& a, size_t n); // freestanding - // \ref{default.allocator}, the default allocator template class allocator; template @@ -878,7 +877,8 @@ \begin{itemdescr} \pnum \mandates -\tcode{T} is an implicit-lifetime type\iref{basic.types.general}. +\tcode{T} is an implicit-lifetime type\iref{basic.types.general} +and not an incomplete type\iref{term.incomplete.type}. \pnum \expects @@ -927,15 +927,34 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + \pnum \expects -\tcode{n > 0} is \tcode{true}. +\tcode{p} is suitably aligned for an array of \tcode{T} or is null. +\tcode{n <= size_t(-1) / sizeof(T)} is \tcode{true}. +If \tcode{n > 0} is \tcode{true}, +\range{(char*)p}{(char*)p + (n * sizeof(T))} denotes +a region of allocated storage that is +a subset of the region of storage +reachable through\iref{basic.compound} \tcode{p}. \pnum \effects -Equivalent to: -\tcode{return *start_lifetime_as(p);} +If \tcode{n > 0} is \tcode{true}, +equivalent to +\tcode{start_lifetime_as(p)} where \tcode{U} is the type ``array of \tcode{n} \tcode{T}''. +Otherwise, there are no effects. + +\pnum +\returns +A pointer to the first element of the created array, +if any; +otherwise, +a pointer that compares equal to \tcode{p}\iref{expr.eq}. \end{itemdescr} \rSec2[allocator.tag]{Allocator argument tag} @@ -1202,6 +1221,28 @@ \end{codeblock} \end{itemdescr} +\indexlibraryglobal{uses_allocator_construction_args}% +\begin{itemdecl} +template + constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{remove_cv_t} is a specialization of \tcode{pair} and +\tcode{remove_cvref_t

} is not a specialization of \tcode{ranges::subrange}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uses_allocator_construction_args(alloc, piecewise_construct, + forward_as_tuple(get<0>(std::forward

(p))), + forward_as_tuple(get<1>(std::forward

(p)))); +\end{codeblock} +\end{itemdescr} + \indexlibraryglobal{uses_allocator_construction_args}% \begin{itemdecl} template @@ -1218,9 +1259,15 @@ \pnum \constraints -\tcode{remove_cv_t} is a specialization of \tcode{pair}, and +\tcode{remove_cv_t} is a specialization of \tcode{pair}, and either: +\begin{itemize} +\item +\tcode{remove_cvref_t} is a specialization of \tcode{ranges::subrange}, or +\item +\tcode{U} does not satisfy \exposconcept{pair-like} and the expression \tcode{\exposid{FUN}(u)} is not well-formed when considered as an unevaluated operand. +\end{itemize} \pnum Let \exposid{pair-constructor} be an exposition-only class defined as follows: @@ -1300,6 +1347,9 @@ Thus, it is always possible to create a derived class from an allocator. \end{note} +If a program declares +an explicit or partial specialization of \tcode{allocator_traits}, +the program is ill-formed, no diagnostic required. \indexlibraryglobal{allocator_traits}% \begin{codeblock} @@ -1328,6 +1378,8 @@ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n); [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); + [[nodiscard]] static constexpr allocation_result + allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); @@ -1514,6 +1566,19 @@ \tcode{a.allocate(n, hint)} if that expression is well-formed; otherwise, \tcode{a.allocate(n)}. \end{itemdescr} +\indexlibrarymember{allocate_at_least}{allocator_traits}% +\begin{itemdecl} +[[nodiscard]] static constexpr allocation_result + allocate_at_least(Alloc& a, size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{a.allocate_at_least(n)} if that expression is well-formed; +otherwise, \tcode{\{a.allocate(n), n\}}. +\end{itemdescr} + \indexlibrarymember{deallocate}{allocator_traits}% \begin{itemdecl} static constexpr void deallocate(Alloc& a, pointer p, size_type n); @@ -1587,19 +1652,6 @@ the template parameters, data members, and special members specified above. It has no base classes or members other than those specified. -\begin{itemdecl} -template -[[nodiscard]] constexpr allocation_result::pointer> - allocate_at_least(Allocator& a, size_t n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{a.allocate_at_least(n)} if that expression is well-formed; -otherwise, \tcode{\{a.allocate(n), n\}}. -\end{itemdescr} - \rSec2[default.allocator]{The default allocator} \rSec3[default.allocator.general]{General} @@ -4962,6 +5014,24 @@ Initializes \tcode{s} with \tcode{smart}, \tcode{a} with \tcode{std::forward(args)...}, and value-initializes \tcode{p}. +Then, equivalent to: +\begin{itemize} +\item +\begin{codeblock} +s.reset(); +\end{codeblock} +if the expression \tcode{s.reset()} is well-formed; + +\item +otherwise, +\begin{codeblock} +s = Smart(); +\end{codeblock} +if \tcode{is_constructible_v} is \tcode{true}; + +\item +otherwise, the program is ill-formed. +\end{itemize} \pnum \begin{note} diff --git a/source/meta.tex b/source/meta.tex index 3ff3f99edb..917869e651 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -245,6 +245,8 @@ template struct is_nothrow_destructible; + template struct is_implicit_lifetime; + template struct has_virtual_destructor; template struct has_unique_object_representations; @@ -519,6 +521,8 @@ constexpr bool @\libglobal{is_nothrow_swappable_v}@ = is_nothrow_swappable::value; template constexpr bool @\libglobal{is_nothrow_destructible_v}@ = is_nothrow_destructible::value; + template + constexpr bool @\libglobal{is_implicit_lifetime_v}@ = is_implicit_lifetime::value; template constexpr bool @\libglobal{has_virtual_destructor_v}@ = has_virtual_destructor::value; template @@ -1199,6 +1203,13 @@ \cv{}~\keyword{void}, or an array of unknown bound. \\ \rowsep +\indexlibraryglobal{is_implicit_lifetime}% +\tcode{template}\br + \tcode{struct is_implicit_lifetime;} & + \tcode{T} is an implicit-lifetime type\iref{basic.types.general}. & + \tcode{T} shall be an array type, + a complete type, or \cv{}~\keyword{void}. \\ \rowsep + \indexlibraryglobal{has_virtual_destructor}% \tcode{template}\br \tcode{struct has_virtual_destructor;} & @@ -1217,19 +1228,46 @@ \indexlibraryglobal{reference_constructs_from_temporary}% \tcode{template}\br \tcode{struct reference_constructs_from_temporary;} & - \tcode{conjunction_v, is_constructible>} - is \tcode{true}, and - the initialization \tcode{T t(\exposidnc{VAL});} binds \tcode{t} to - a temporary object whose lifetime is extended\iref{class.temporary}. & + \tcode{T} is a reference type, and + the initialization \tcode{T t(\exposidnc{VAL});} is + well-formed and binds \tcode{t} to + a temporary object whose lifetime is extended\iref{class.temporary}. + Access checking is performed as if in + a context unrelated to \tcode{T} and \tcode{U}. + Only the validity of the immediate context of + the variable initialization is considered. + \begin{tailnote} + The initialization can result in effects such as + the instantiation of class template specializations and + function template specializations, + the generation of implicitly-defined functions, and so on. + Such effects are not in the ``immediate context'' and + can result in the program being ill-formed. + \end{tailnote} +& \tcode{T} and \tcode{U} shall be complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep \indexlibraryglobal{reference_converts_from_temporary}% \tcode{template}\br \tcode{struct reference_converts_from_temporary;} & - \tcode{conjunction_v, is_convertible>} is \tcode{true}, - and the initialization \tcode{T t = \exposidnc{VAL};} binds \tcode{t} to - a temporary object whose lifetime is extended\iref{class.temporary}. & + \tcode{T} is a reference type, and + the initialization \tcode{T t = \exposidnc{VAL};} + is well-formed and binds \tcode{t} to + a temporary object whose lifetime is extended\iref{class.temporary}. + Access checking is performed as if in + a context unrelated to \tcode{T} and \tcode{U}. + Only the validity of the immediate context of + the variable initialization is considered. + \begin{tailnote} + The initialization can result in effects such as + the instantiation of class template specializations and + function template specializations, + the generation of implicitly-defined functions, and so on. + Such effects are not in the ``immediate context'' and + can result in the program being ill-formed. + \end{tailnote} +& \tcode{T} and \tcode{U} shall be complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep @@ -2083,9 +2121,11 @@ \item Otherwise, if \tcode{sizeof...(T)} is two, let \tcode{T1} and \tcode{T2} denote the two types in the pack \tcode{T}. Then \begin{itemize} - \item If \tcode{T1} and \tcode{T2} are reference types and - \tcode{\placeholdernc{COMMON-REF}(T1, T2)} is well-formed, then the member - typedef \tcode{type} denotes that type. + \item Let \tcode{R} be \tcode{\placeholdernc{COMMON-REF}(T1, T2)}. + If \tcode{T1} and \tcode{T2} are reference types, + \tcode{R} is well-formed, and + \tcode{is_convertible_v, add_pointer_t> \&\& is_convertible_v, add_pointer_t>} is \tcode{true}, + then the member typedef \tcode{type} denotes \tcode{R}. \item Otherwise, if \tcode{basic_common_reference, remove_cvref_t, diff --git a/source/modules.tex b/source/modules.tex index 0a65f8c069..f38503d39e 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -512,6 +512,13 @@ \end{footnote} These rules can in turn lead to the importation of yet more translation units. +\begin{note} +Such indirect importation does not make macros available, +because a translation unit is +a sequence of tokens in translation phase 7\iref{lex.phases}. +Macros can be made available by directly importing header units +as described in \ref{cpp.import}. +\end{note} \pnum A module implementation unit shall not be exported. diff --git a/source/numerics.tex b/source/numerics.tex index e5b998e1ed..785bb29f51 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -9160,7 +9160,7 @@ constexpr float nextafterf(float x, float y); constexpr long double nextafterl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ nexttoward(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr @\placeholder{floating-point-type}@ nexttoward(@\placeholder{floating-point-type}@ x, long double y); constexpr float nexttowardf(float x, long double y); constexpr long double nexttowardl(long double x, long double y); @@ -9349,6 +9349,11 @@ a usable candidate\iref{over.match.general} from the overloads provided by the implementation. +\pnum +An invocation of \tcode{nexttoward} is ill-formed if +the argument corresponding to the \placeholder{floating-point-type} parameter +has extended floating-point type. + \xrefc{7.12} \rSec2[c.math.abs]{Absolute values} diff --git a/source/overloading.tex b/source/overloading.tex index ec0d55b2fc..b9f47ea50b 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -154,15 +154,17 @@ \indextext{function!overload resolution and}% The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. -So that argument and parameter lists are comparable within this -heterogeneous set, a member function that does not have an explicit object parameter is considered to have an -extra first parameter, called the -\defn{implicit object parameter}, -which represents the object for which the member function has been -called. -For the purposes of overload resolution, both static and -non-static member functions have an object parameter, -but constructors do not. +If a member function is +\begin{itemize} +\item +an implicit object member function that is not a constructor, or +\item +a static member function and +the argument list includes an implied object argument, +\end{itemize} +it is considered to have an extra first parameter, +called the \defnadj{implicit}{object parameter}, +which represents the object for which the member function has been called. \pnum Similarly, when appropriate, the context can construct an @@ -367,7 +369,11 @@ \pnum If the \grammarterm{postfix-expression} is the address of an overload set, overload resolution is applied using that set as described above. -If the function selected by overload resolution is a non-static member function, +\begin{note} +No implied object argument is added in this case. +\end{note} +If the function selected by overload resolution is +an implicit object member function, the program is ill-formed. \begin{note} The resolution of the address of an @@ -443,15 +449,16 @@ The function declarations found by name lookup\iref{basic.lookup} constitute the set of candidate functions. Because of the rules for name lookup, the set of candidate functions -consists (1) entirely of non-member functions or (2) entirely of +consists either entirely of non-member functions or entirely of member functions of some class \tcode{T}. -In case (1), +In the former case or +if the \grammarterm{primary-expression} is the address of an overload set, the argument list is the same as the \grammarterm{expression-list} in the call. -In case (2), the argument list is the +Otherwise, the argument list is the \grammarterm{expression-list} in the call augmented by the addition of an implied object argument as in a qualified function call. @@ -485,6 +492,19 @@ a(); // OK, \tcode{(*this).a()} } +void c(this const C&); // \#1 +void c()&; // \#2 +static void c(int = 0); // \#3 + +void d() { + c(); // error: ambiguous between \#2 and \#3 + (C::c)(); // error: as above + (&(C::c))(); // error: cannot resolve address of overloaded \tcode{this->C::c}\iref{over.over} + (&C::c)(C{}); // selects \#1 + (&C::c)(*this); // error: selects \#2, and is ill-formed\iref{over.match.call.general} + (&C::c)(); // selects \#3 +} + void f(this const C&); void g() const { f(); // OK, \tcode{(*this).f()} @@ -723,6 +743,7 @@ operands can be converted according to \ref{over.best.ics}, and \item do not have the same parameter-type-list as any non-member candidate +or rewritten non-member candidate that is not a function template specialization. \end{itemize} @@ -1240,8 +1261,12 @@ \begin{itemize} \item brace elision is not considered for any aggregate element -that has a dependent non-array type or -an array type with a value-dependent bound, and +that has +\begin{itemize} +\item a dependent non-array type, +\item an array type with a value-dependent bound, or +\item an array type with a dependent array element type and $x_i$ is a string literal; and +\end{itemize} \item each non-trailing aggregate element that is a pack expansion is assumed to correspond to no elements of the initializer list, and @@ -1257,9 +1282,14 @@ \begin{itemize} \item if $e_i$ is of array type and -$x_i$ is a \grammarterm{braced-init-list} or \grammarterm{string-literal}, +$x_i$ is a \grammarterm{braced-init-list}, $\tcode{T}_i$ is an rvalue reference to the declared type of $e_i$, and \item +if $e_i$ is of array type and +$x_i$ is a \grammarterm{string-literal}, +$\tcode{T}_i$ is an lvalue reference to +the const-qualified declared type of $e_i$, and +\item otherwise, $\tcode{T}_i$ is the declared type of $e_i$, \end{itemize} except that additional parameter packs of the form $\tcode{P}_j \tcode{...}$ @@ -1329,6 +1359,23 @@ } G g(true, 'a', 1); // OK, deduces \tcode{G} + +template +struct H { + T array[N]; +}; +template +struct I { + volatile T array[N]; +}; +template +struct J { + unsigned char array[N]; +}; + +H h = { "abc" }; // OK, deduces \tcode{H} (not \tcode{T = const char}) +I i = { "def" }; // OK, deduces \tcode{I} +J j = { "ghi" }; // error: cannot bind reference to array of \tcode{unsigned char} to array of \tcode{char} in deduction \end{codeblock} \end{example} @@ -1351,6 +1398,8 @@ according to the process in \ref{temp.deduct.type} with the exception that deduction does not fail if not all template arguments are deduced. +If deduction fails for another reason, +proceed with an empty set of deduced template arguments. Let \tcode{g} denote the result of substituting these deductions into \tcode{f}. If substitution succeeds, @@ -3004,7 +3053,7 @@ explicit object member functions match targets of function pointer type or reference to function type. -Non-static member functions match targets of +Implicit object member functions match targets of pointer-to-member-function type. \begin{note} %% FIXME: Should this only apply after the eliminations in the next paragraph? @@ -3905,6 +3954,7 @@ The \grammarterm{ud-suffix} of the \grammarterm{user-defined-string-literal} or the \grammarterm{identifier} in a \grammarterm{literal-operator-id} is called a \defnx{literal suffix identifier}{literal!suffix identifier}. +The first form of \grammarterm{literal-operator-id} is deprecated. Some literal suffix identifiers are reserved for future standardization; see~\ref{usrlit.suffix}. A declaration whose \grammarterm{literal-operator-id} uses such a literal suffix identifier is ill-formed, no diagnostic required. @@ -3979,19 +4029,19 @@ \pnum \begin{example} \begin{codeblock} -void operator "" _km(long double); // OK -string operator "" _i18n(const char*, std::size_t); // OK -template double operator "" _\u03C0(); // OK, UCN for lowercase pi +void operator ""_km(long double); // OK +string operator "" _i18n(const char*, std::size_t); // OK, deprecated +template double operator ""_\u03C0(); // OK, UCN for lowercase pi float operator ""_e(const char*); // OK float operator ""E(const char*); // ill-formed, no diagnostic required: // reserved literal suffix\iref{usrlit.suffix,lex.ext} double operator""_Bq(long double); // OK, does not use the reserved \grammarterm{identifier} \tcode{_Bq}\iref{lex.name} double operator"" _Bq(long double); // ill-formed, no diagnostic required: // uses the reserved \grammarterm{identifier} \tcode{_Bq}\iref{lex.name} -float operator " " B(const char*); // error: non-empty \grammarterm{string-literal} -string operator "" 5X(const char*, std::size_t); // error: invalid literal suffix identifier -double operator "" _miles(double); // error: invalid \grammarterm{parameter-declaration-clause} -template int operator "" _j(const char*); // error: invalid \grammarterm{parameter-declaration-clause} -extern "C" void operator "" _m(long double); // error: C language linkage +float operator " "B(const char*); // error: non-empty \grammarterm{string-literal} +string operator ""5X(const char*, std::size_t); // error: invalid literal suffix identifier +double operator ""_miles(double); // error: invalid \grammarterm{parameter-declaration-clause} +template int operator ""_j(const char*); // error: invalid \grammarterm{parameter-declaration-clause} +extern "C" void operator ""_m(long double); // error: C language linkage \end{codeblock} \end{example} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index d01c69babf..5ad072c5c1 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -82,8 +82,8 @@ \begin{bnf}\obeyspaces \nontermdef{elif-group}\br \terminal{\# elif } constant-expression new-line \opt{group}\br - \terminal{\# elifdef } constant-expression new-line \opt{group}\br - \terminal{\# elifndef} constant-expression new-line \opt{group} + \terminal{\# elifdef } identifier new-line \opt{group}\br + \terminal{\# elifndef} identifier new-line \opt{group} \end{bnf} \begin{bnf}\obeyspaces @@ -929,6 +929,18 @@ int a = Y; // OK, active macro definitions \#2 and \#4 are valid redefinitions int c = Z; // error: active macro definitions \#3 and \#5 are not valid redefinitions of \tcode{Z} \end{codeblocktu} + +\begin{codeblocktu}{Module unit \tcode{f}} +export module f; +export import "a.h"; + +int a = Y; // OK +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \tcode{\#1}} +import f; +int x = Y; // error: \tcode{Y} is neither a defined macro nor a declared name +\end{codeblocktu} \end{example} \indextext{macro!import|)} @@ -1836,7 +1848,7 @@ \defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep \defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep \defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep -\defnxname{cpp_range_based_for} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep \defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep \defnxname{cpp_ref_qualifiers} & \tcode{200710L} \\ \rowsep \defnxname{cpp_return_type_deduction} & \tcode{201304L} \\ \rowsep @@ -1883,13 +1895,11 @@ \item \indextext{__stdc_iso_10646__@\mname{STDC_ISO_10646}}% \mname{STDC_ISO_10646}\\ -An integer literal of the form \tcode{yyyymmL} (for example, -\tcode{199712L}). -If this symbol is defined, then every character in the Unicode required set, when -stored in an object of type \keyword{wchar_t}, has the same value as the code point -of that character. The \defn{Unicode required set} consists of all -the characters that are defined by ISO/IEC 10646, along with -all amendments and technical corrigenda as of the specified year and month. +An integer literal of the form \tcode{yyyymmL} +(for example, \tcode{199712L}). +Whether \mname{STDC_ISO_10646} is predefined and +if so, what its value is, +are \impldef{presence and value of \mname{STDC_ISO_10646}}. \item \indextext{__stdcpp_threads__@\mname{STDCPP_THREADS}}% diff --git a/source/ranges.tex b/source/ranges.tex index 33bf7dd175..03c4ea1eaf 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -80,6 +80,8 @@ using range_const_reference_t = iter_const_reference_t>; // freestanding template<@\libconcept{range}@ R> using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding + template<@\libconcept{range}@ R> + using range_common_reference_t = iter_common_reference_t>; // freestanding // \ref{range.sized}, sized ranges template @@ -212,8 +214,7 @@ // \ref{range.repeat}, repeat view template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> - requires (is_object_v && @\libconcept{same_as}@> - && (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + requires @\seebelow@ class repeat_view; // freestanding namespace views { inline constexpr @\unspecnc@ repeat = @\unspecnc@; } // freestanding @@ -431,6 +432,17 @@ inline constexpr auto @\libmember{values}{views}@ = elements<1>; // freestanding } + // \ref{range.enumerate}, enumerate view + template<@\libconcept{input_range}@ View> + requires @\libconcept{view}@ + class enumerate_view; // freestanding + + template + constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; + + namespace views { inline constexpr @\unspecnc@ enumerate = @\unspecnc@; } // freestanding + // \ref{range.zip}, zip view template<@\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) @@ -1633,6 +1645,11 @@ template concept @\defexposconceptnc{different-from}@ = // \expos !@\libconcept{same_as}@, remove_cvref_t>; + +template + concept @\defexposconceptnc{range-with-movable-references}@ = // \expos + @\libconcept{input_range}@ && @\libconcept{move_constructible}@> && + @\libconcept{move_constructible}@>; \end{codeblock} \rSec2[view.interface]{View interface} @@ -1813,7 +1830,7 @@ I @\exposid{begin_}@ = I(); // \expos S @\exposid{end_}@ = S(); // \expos @\exposidnc{make-unsigned-like-t}@> @\exposid{size_}@ = 0; // \expos; present only - // when \exposid{StoreSize} is \tcode{true} + // if \exposid{StoreSize} is \tcode{true} public: subrange() requires @\libconcept{default_initializable}@ = default; @@ -2270,6 +2287,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{C} is a cv-unqualified class type. + \pnum \returns An object of type \tcode{C} @@ -2298,7 +2319,10 @@ \item \tcode{\libconcept{common_range}} is \tcode{true}, \item -\tcode{\exposconcept{cpp17-input-iterator}>} is \tcode{true}, and +the \grammarterm{qualified-id} +\tcode{iterator_traits>::iterator_category} +is valid and denotes a type that models +\tcode{\libconcept{derived_from}}, and \item \tcode{\libconcept{constructible_from}, sentinel_t, Args...>} is \tcode{true}: @@ -2398,6 +2422,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +For the first overload, +\tcode{C} is a cv-unqualified class type. + \pnum \returns A range adaptor closure object\iref{range.adaptor.object} \tcode{f} @@ -2522,7 +2551,7 @@ \indexlibraryctor{single_view}% \begin{itemdecl} -constexpr explicit single_view(const T& t) requires @\libconcept{copy_constructible}@;; +constexpr explicit single_view(const T& t) requires @\libconcept{copy_constructible}@; \end{itemdecl} \begin{itemdescr} @@ -2655,8 +2684,8 @@ public: iota_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit iota_view(W value); - constexpr iota_view(type_identity_t value, type_identity_t bound); - constexpr iota_view(@\exposid{iterator}@ first, @\seebelow@ last); + constexpr explicit iota_view(type_identity_t value, type_identity_t bound); + constexpr explicit iota_view(@\exposid{iterator}@ first, @\seebelow@ last); constexpr @\exposid{iterator}@ begin() const; constexpr auto end() const; @@ -2789,7 +2818,7 @@ \indexlibraryctor{iota_view}% \begin{itemdecl} -constexpr iota_view(type_identity_t value, type_identity_t bound); +constexpr explicit iota_view(type_identity_t value, type_identity_t bound); \end{itemdecl} \begin{itemdescr} @@ -2808,7 +2837,7 @@ \indexlibraryctor{iota_view}% \begin{itemdecl} -constexpr iota_view(@\exposid{iterator}@ first, @\seebelow@ last); +constexpr explicit iota_view(@\exposid{iterator}@ first, @\seebelow@ last); \end{itemdecl} \begin{itemdescr} @@ -3386,9 +3415,14 @@ \begin{codeblock} namespace std::ranges { + template + concept @\defexposconceptnc{integer-like-with-usable-difference-type}@ = // \expos + @\exposid{is-signed-integer-like}@ || (@\exposid{is-integer-like}@ && @\libconcept{weakly_incrementable}@); + template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires (is_object_v && @\libconcept{same_as}@> && - (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + (@\exposconcept{integer-like-with-usable-difference-type}@ || + @\libconcept{same_as}@)) class @\libglobal{repeat_view}@ : public view_interface> { private: // \ref{range.repeat.iterator}, class \tcode{repeat_view::\exposid{iterator}} @@ -3467,12 +3501,14 @@ \begin{itemdescr} \pnum \effects -Initializes \exposid{value_} with arguments of types \tcode{TArgs...} -obtained by forwarding the elements of \tcode{value_args} and -initializes \exposid{bound_} with arguments of types \tcode{BoundArgs...} -obtained by forwarding the elements of \tcode{bound_args}. -(Here, forwarding an element \tcode{x} of type \tcode{U} within a tuple object -means calling \tcode{std::forward(x)}.) +Initializes \exposid{value_} with +\tcode{make_from_tuple(std::move(value_args))} +and +initializes\linebreak{} \exposid{bound_} with +\tcode{make_from_tuple(std::move(bound_args))}. +The behavior is undefined if +\tcode{Bound} is not \tcode{unreachable_sentinel_t} and +\exposid{bound_} is negative. \end{itemdescr} \indexlibrarymember{begin}{repeat_view}% @@ -3523,9 +3559,10 @@ \begin{codeblock} namespace std::ranges { - template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound> requires (is_object_v && @\libconcept{same_as}@> && - (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + (@\exposconcept{integer-like-with-usable-difference-type}@ || + @\libconcept{same_as}@)) class repeat_view::@\exposid{iterator}@ { private: using @\exposidnc{index-type}@ = // \expos @@ -3539,9 +3576,7 @@ using iterator_concept = random_access_iterator_tag; using iterator_category = random_access_iterator_tag; using value_type = T; - using difference_type = conditional_t<@\exposid{is-signed-integer-like}@<@\exposid{index-type}@>, - @\exposid{index-type}@, - @\placeholdernc{IOTA-DIFF-T}@(@\exposid{index-type}@)>; + using difference_type = @\seebelow@; @\exposid{iterator}@() = default; @@ -3569,6 +3604,12 @@ } \end{codeblock} +\pnum +If \tcode{\exposid{is-signed-integer-like}<\exposid{index-type}>} is \tcode{true}, +the member \grammarterm{typedef-name} \tcode{difference_type} +denotes \exposid{index-type}. +Otherwise, it denotes \tcode{\placeholdernc{IOTA-DIFF-T}(\exposid{index-type})}\iref{range.iota.view}. + \indexlibraryctor{repeat_view::\exposid{iterator}}% \begin{itemdecl} constexpr explicit @\exposid{iterator}@(const T* value, @\exposid{index-type}@ b = @\exposid{index-type}@()); @@ -4242,7 +4283,7 @@ to temporarily cache values as it is iterated over. \end{note} -\rSec2[range.adaptor.tuple]{Range adaptor helpers} +\rSec2[range.adaptor.helpers]{Range adaptor helpers} \begin{codeblock} namespace std::ranges { @@ -4259,6 +4300,11 @@ (static_cast(invoke(f, std::forward(elements))), ...); }, std::forward(t)); } + + template + constexpr T& @\exposid{as-lvalue}@(T&& t) { // \expos + return static_cast(t); + } } \end{codeblock} @@ -4419,7 +4465,7 @@ \tcode{as_rvalue_view} presents a view of an underlying sequence with the same behavior as the underlying sequence except that its elements are rvalues. -Some generic algorithms can be called with a \tcode{as_rvalue_view} +Some generic algorithms can be called with an \tcode{as_rvalue_view} to replace copying with moving. \pnum @@ -4549,7 +4595,7 @@ public: filter_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr filter_view(V base, Pred pred); + constexpr explicit filter_view(V base, Pred pred); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -4572,7 +4618,7 @@ \indexlibraryctor{filter_view}% \begin{itemdecl} -constexpr filter_view(V base, Pred pred); +constexpr explicit filter_view(V base, Pred pred); \end{itemdecl} \begin{itemdescr} @@ -4976,7 +5022,7 @@ public: transform_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr transform_view(V base, F fun); + constexpr explicit transform_view(V base, F fun); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -5007,7 +5053,7 @@ \indexlibraryctor{transform_view}% \begin{itemdecl} -constexpr transform_view(V base, F fun); +constexpr explicit transform_view(V base, F fun); \end{itemdecl} \begin{itemdescr} @@ -5630,7 +5676,7 @@ \begin{itemize} \item If \tcode{T} is a specialization -of \tcode{ranges::empty_view}\iref{range.empty.view}, +of \tcode{empty_view}\iref{range.empty.view}, then \tcode{((void)F, \placeholdernc{decay-copy}(E))}, except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. @@ -5641,7 +5687,7 @@ and is a specialization of \tcode{span}\iref{views.span}, \tcode{basic_string_view}\iref{string.view}, or -\tcode{ranges::subrange}\iref{range.subrange}, +\tcode{subrange}\iref{range.subrange}, then \tcode{U(ranges::begin(E), ranges::be\-gin(E) + std::min(ranges::distance(E), F))}, @@ -5653,22 +5699,22 @@ then \tcode{U} is \tcode{span}; \item otherwise, if \tcode{T} is a specialization of \tcode{basic_string_view}, then \tcode{U} is \tcode{T}; -\item otherwise, \tcode{T} is a specialization of \tcode{ranges::subrange}, and -\tcode{U} is \tcode{ranges::subrange>}; +\item otherwise, \tcode{T} is a specialization of \tcode{subrange}, and +\tcode{U} is \tcode{subrange>}; \end{itemize} \item otherwise, if \tcode{T} is -a specialization of \tcode{ranges::iota_view}\iref{range.iota.view} +a specialization of \tcode{iota_view}\iref{range.iota.view} that models \libconcept{random_access_range} and \libconcept{sized_range}, then -\tcode{ranges::iota_view(*ranges::begin(E), +\tcode{iota_view(*ranges::begin(E), *(ranges::begin(E) + std::\linebreak{}min(ranges::distance(E), F)))}, except that \tcode{E} is evaluated only once. \item Otherwise, if \tcode{T} is -a specialization of \tcode{ranges::repeat_view}\iref{range.repeat.view}: +a specialization of \tcode{repeat_view}\iref{range.repeat.view}: \begin{itemize} \item if \tcode{T} models \libconcept{sized_range}, @@ -5682,7 +5728,7 @@ \end{itemize} \item -Otherwise, \tcode{ranges::take_view(E, F)}. +Otherwise, \tcode{take_view(E, F)}. \end{itemize} \pnum @@ -5714,7 +5760,7 @@ public: take_view() requires @\libconcept{default_initializable}@ = default; - constexpr take_view(V base, range_difference_t count); + constexpr explicit take_view(V base, range_difference_t count); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -5798,7 +5844,7 @@ \indexlibraryctor{take_view}% \begin{itemdecl} -constexpr take_view(V base, range_difference_t count); +constexpr explicit take_view(V base, range_difference_t count); \end{itemdecl} \begin{itemdescr} @@ -5945,7 +5991,7 @@ public: take_while_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr take_while_view(V base, Pred pred); + constexpr explicit take_while_view(V base, Pred pred); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -5976,7 +6022,7 @@ \indexlibraryctor{take_while_view}% \begin{itemdecl} -constexpr take_while_view(V base, Pred pred); +constexpr explicit take_while_view(V base, Pred pred); \end{itemdecl} \begin{itemdescr} @@ -6095,7 +6141,7 @@ \begin{itemize} \item If \tcode{T} is a specialization of -\tcode{ranges::empty_view}\iref{range.empty.view}, +\tcode{empty_view}\iref{range.empty.view}, then \tcode{((void)F, \placeholdernc{decay-copy}(E))}, except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. @@ -6107,8 +6153,8 @@ \begin{itemize} \item a specialization of \tcode{span}\iref{views.span}, \item a specialization of \tcode{basic_string_view}\iref{string.view}, -\item a specialization of \tcode{ranges::iota_view}\iref{range.iota.view}, or -\item a specialization of \tcode{ranges::subrange}\iref{range.subrange} +\item a specialization of \tcode{iota_view}\iref{range.iota.view}, or +\item a specialization of \tcode{subrange}\iref{range.subrange} where \tcode{T::\exposid{StoreSize}} is \tcode{false}, \end{itemize} then \tcode{U(ranges::begin(E) + std::min(ranges::distance(E), F), ranges::end(E))}, @@ -6119,7 +6165,7 @@ \item Otherwise, if \tcode{T} is -a specialization of \tcode{ranges::subrange}\iref{range.subrange} +a specialization of \tcode{subrange}\iref{range.subrange} that models \libconcept{random_access_range} and \libconcept{sized_range}, then \tcode{T(ranges::begin(E) + std::min(ranges::distance(E), F), ranges::\linebreak{}end(E), @@ -6129,7 +6175,7 @@ \item Otherwise, if \tcode{T} is -a specialization of \tcode{ranges::repeat_view}\iref{range.repeat.view}: +a specialization of \tcode{repeat_view}\iref{range.repeat.view}: \begin{itemize} \item if \tcode{T} models \libconcept{sized_range}, @@ -6144,7 +6190,7 @@ \end{itemize} \item -Otherwise, \tcode{ranges::drop_view(E, F)}. +Otherwise, \tcode{drop_view(E, F)}. \end{itemize} \pnum @@ -6169,7 +6215,7 @@ class drop_view : public view_interface> { public: drop_view() requires @\libconcept{default_initializable}@ = default; - constexpr drop_view(V base, range_difference_t count); + constexpr explicit drop_view(V base, range_difference_t count); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -6210,7 +6256,7 @@ \indexlibraryctor{drop_view}% \begin{itemdecl} -constexpr drop_view(V base, range_difference_t count); +constexpr explicit drop_view(V base, range_difference_t count); \end{itemdecl} \begin{itemdescr} @@ -6294,7 +6340,7 @@ class drop_while_view : public view_interface> { public: drop_while_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr drop_while_view(V base, Pred pred); + constexpr explicit drop_while_view(V base, Pred pred); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -6317,7 +6363,7 @@ \indexlibraryctor{drop_while_view}% \begin{itemdecl} -constexpr drop_while_view(V base, Pred pred); +constexpr explicit drop_while_view(V base, Pred pred); \end{itemdecl} \begin{itemdescr} @@ -6414,8 +6460,10 @@ V @\exposid{base_}@ = V(); // \expos + @\exposidnc{non-propagating-cache}@> @\exposidnc{outer_}@; // \expos, present only + // when \tcode{!\libconcept{forward_range}} @\exposidnc{non-propagating-cache}@> @\exposid{inner_}@; // \expos, present only - // when \tcode{!is_reference_v<\exposid{InnerRng}>} + // if \tcode{is_reference_v<\exposid{InnerRng}>} is \tcode{false} public: join_view() requires @\libconcept{default_initializable}@ = default; @@ -6425,14 +6473,20 @@ constexpr V base() && { return std::move(@\exposid{base_}@); } constexpr auto begin() { - constexpr bool use_const = @\exposconcept{simple-view}@ && - is_reference_v<@\exposid{InnerRng}@>; - return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; + if constexpr (@\libconcept{forward_range}@) { + constexpr bool use_const = @\exposconcept{simple-view}@ && + is_reference_v<@\exposid{InnerRng}@>; + return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; + } else { + @\exposid{outer_}@ = ranges::begin(@\exposid{base_}@); + return @\exposid{iterator}@{*this}; + } } constexpr auto begin() const - requires @\libconcept{input_range}@ && - is_reference_v> + requires @\libconcept{forward_range}@ && + is_reference_v> && + @\libconcept{input_range}@> { return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; } constexpr auto end() { @@ -6445,10 +6499,10 @@ } constexpr auto end() const - requires @\libconcept{input_range}@ && - is_reference_v> { - if constexpr (@\libconcept{forward_range}@ && - @\libconcept{forward_range}@> && + requires @\libconcept{forward_range}@ && + is_reference_v> && + @\libconcept{input_range}@> { + if constexpr (@\libconcept{forward_range}@> && @\libconcept{common_range}@ && @\libconcept{common_range}@>) return @\exposid{iterator}@{*this, ranges::end(@\exposid{base_}@)}; @@ -6490,20 +6544,28 @@ static constexpr bool @\exposidnc{ref-is-glvalue}@ = // \expos is_reference_v>; - @\exposidnc{OuterIter}@ @\exposid{outer_}@ = @\exposidnc{OuterIter}@(); // \expos + @\exposidnc{OuterIter}@ @\exposid{outer_}@ = @\exposidnc{OuterIter}@(); // \expos, present only + // if \exposid{Base} models \libconcept{forward_range} optional<@\exposidnc{InnerIter}@> @\exposid{inner_}@; // \expos @\exposidnc{Parent}@* @\exposid{parent_}@ = nullptr; // \expos constexpr void @\exposidnc{satisfy}@(); // \expos + constexpr @\exposidnc{OuterIter}@& @\exposidnc{outer}@(); // \expos + constexpr const @\exposidnc{OuterIter}@& @\exposidnc{outer}@() const; // \expos + + constexpr @\exposidnc{iterator}@(@\exposidnc{Parent}@& parent, @\exposidnc{OuterIter}@ outer) + requires @\libconcept{forward_range}@<@\exposidnc{Base}@>; // \expos + constexpr explicit @\exposidnc{iterator}@(@\exposidnc{Parent}@& parent) + requires (!@\libconcept{forward_range}@<@\exposidnc{Base}@>); // \expos + public: using iterator_concept = @\seebelow@; using iterator_category = @\seebelow@; // not always present using value_type = range_value_t>; using difference_type = @\seebelow@; - @\exposid{iterator}@() requires @\libconcept{default_initializable}@<@\exposid{OuterIter}@> = default; - constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{OuterIter}@ outer); + @\exposid{iterator}@() = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@, @\exposid{OuterIter}@> && @@ -6531,7 +6593,7 @@ @\libconcept{common_range}@>; friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposid{ref-is-glvalue}@ && @\libconcept{equality_comparable}@> && + requires @\exposid{ref-is-glvalue}@ && @\libconcept{forward_range}@<@\exposid{Base}@> && @\libconcept{equality_comparable}@>>; friend constexpr decltype(auto) iter_move(const @\exposid{iterator}@& i) @@ -6598,6 +6660,18 @@ \tcode{join_view} iterators use the \exposid{satisfy} function to skip over empty inner ranges. +\begin{itemdecl} +constexpr @\exposid{OuterIter}@& @\exposid{outer}@(); +constexpr const @\exposid{OuterIter}@& @\exposid{outer}@() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{outer_} if \exposid{Base} models \libconcept{forward_range}; +otherwise, \tcode{*\exposid{parent_}->\exposid{outer_}}. +\end{itemdescr} + \begin{itemdecl} constexpr void @\exposid{satisfy}@(); \end{itemdecl} @@ -6614,8 +6688,8 @@ return @\exposid{parent_}@->@\exposid{inner_}@.@\exposid{emplace-deref}@(x); }; -for (; @\exposid{outer_}@ != ranges::end(@\exposid{parent_}@->@\exposid{base_}@); ++@\exposid{outer_}@) { - auto&& inner = update_inner(@\exposid{outer_}@); +for (; @\exposid{outer}@() != ranges::end(@\exposid{parent_}@->@\exposid{base_}@); ++@\exposid{outer}@()) { + auto&& inner = update_inner(@\exposid{outer}@()); @\exposid{inner_}@ = ranges::begin(inner); if (*@\exposid{inner_}@ != ranges::end(inner)) return; @@ -6627,7 +6701,8 @@ \indexlibraryctor{join_view::\exposid{iterator}}% \begin{itemdecl} -constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{OuterIter}@ outer); +constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{OuterIter}@ outer) + requires @\libconcept{forward_range}@<@\exposid{Base}@>; \end{itemdecl} \begin{itemdescr} @@ -6637,6 +6712,19 @@ \exposid{parent_} with \tcode{addressof(parent)}; then calls \tcode{\exposid{satisfy}()}. \end{itemdescr} +\indexlibraryctor{join_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(@\exposid{Parent}@& parent) + requires (!@\libconcept{forward_range}@<@\exposid{Base}@>); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{parent_} with \tcode{addressof(parent)}; +then calls \tcode{\exposid{satisfy}()}. +\end{itemdescr} + \indexlibraryctor{join_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) @@ -6651,6 +6739,12 @@ Initializes \exposid{outer_} with \tcode{std::move(i.\exposid{outer_})}, \exposid{inner_} with \tcode{std::move(i.\exposid{inner_})}, and \exposid{parent_} with \tcode{i.\exposid{parent_}}. + +\pnum +\begin{note} +\tcode{Const} can only be \tcode{true} +when \exposid{Base} models \libconcept{forward_range}. +\end{note} \end{itemdescr} \indexlibrarymember{operator->}{join_view::\exposid{iterator}}% @@ -6674,7 +6768,7 @@ \pnum Let \tcode{\placeholder{inner-range}} be: \begin{itemize} -\item If \exposid{ref-is-glvalue} is \tcode{true}, \tcode{*\exposid{outer_}}. +\item If \exposid{ref-is-glvalue} is \tcode{true}, \tcode{*\exposid{outer}()}. \item Otherwise, \tcode{*\exposid{parent_}->\exposid{inner_}}. \end{itemize} @@ -6682,9 +6776,8 @@ \effects Equivalent to: \begin{codeblock} -auto&& inner_rng = @\placeholder{inner-range}@; -if (++*@\exposid{inner_}@ == ranges::end(inner_rng)) { - ++@\exposid{outer_}@; +if (++*@\exposid{inner_}@ == ranges::end(@\exposid{as-lvalue}@(@\placeholder{inner-range}@))) { + ++@\exposid{outer}@(); @\exposid{satisfy}@(); } return *this; @@ -6734,9 +6827,9 @@ Equivalent to: \begin{codeblock} if (@\exposid{outer_}@ == ranges::end(@\exposid{parent_}@->@\exposid{base_}@)) - @\exposid{inner_}@ = ranges::end(*--@\exposid{outer_}@); -while (*@\exposid{inner_}@ == ranges::begin(*@\exposid{outer_}@)) - *@\exposid{inner_}@ = ranges::end(*--@\exposid{outer_}@); + @\exposid{inner_}@ = ranges::end(@\exposid{as-lvalue}@(*--@\exposid{outer_}@)); +while (*@\exposid{inner_}@ == ranges::begin(@\exposid{as-lvalue}@(*@\exposid{outer_}@))) + *@\exposid{inner_}@ = ranges::end(@\exposid{as-lvalue}@(*--@\exposid{outer_}@)); --*@\exposid{inner_}@; return *this; \end{codeblock} @@ -6764,7 +6857,7 @@ \indexlibrarymember{operator==}{join_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposid{ref-is-glvalue}@ && @\libconcept{equality_comparable}@> && + requires @\exposid{ref-is-glvalue}@ && @\libconcept{forward_range}@<@\exposid{Base}@> && @\libconcept{equality_comparable}@>>; \end{itemdecl} @@ -6849,7 +6942,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return x.\exposid{outer_} == y.\exposid{end_};} +Equivalent to: \tcode{return x.\exposid{outer}() == y.\exposid{end_};} \end{itemdescr} \rSec2[range.join.with]{Join with view} @@ -6903,8 +6996,10 @@ using @\exposid{InnerRng}@ = range_reference_t; // \expos V @\exposid{base_}@ = V(); // \expos + @\exposid{non-propagating-cache}@> @\exposid{outer_it_}@; // \expos, present only + // when \tcode{!\libconcept{forward_range}} @\exposid{non-propagating-cache}@> @\exposid{inner_}@; // \expos, present only - // when \tcode{!is_reference_v<\exposid{InnerRng}>} + // if \tcode{is_reference_v<\exposid{InnerRng}>} is \tcode{false} Pattern @\exposid{pattern_}@ = Pattern(); // \expos // \ref{range.join.with.iterator}, class template \tcode{join_with_view::\exposid{iterator}} @@ -6917,25 +7012,32 @@ join_with_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr join_with_view(V base, Pattern pattern); + constexpr explicit join_with_view(V base, Pattern pattern); template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> - constexpr join_with_view(R&& r, range_value_t<@\exposid{InnerRng}@> e); + constexpr explicit join_with_view(R&& r, range_value_t<@\exposid{InnerRng}@> e); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } constexpr auto begin() { - constexpr bool use_const = - @\exposconcept{simple-view}@ && is_reference_v<@\exposid{InnerRng}@> && @\exposconcept{simple-view}@; - return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; + if constexpr (@\libconcept{forward_range}@) { + constexpr bool use_const = + @\exposconcept{simple-view}@ && is_reference_v<@\exposid{InnerRng}@> && @\exposconcept{simple-view}@; + return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; + } + else { + @\exposid{outer_it_}@ = ranges::begin(@\exposid{base_}@); + return @\exposid{iterator}@{*this}; + } } constexpr auto begin() const - requires @\libconcept{input_range}@ && + requires @\libconcept{forward_range}@ && @\libconcept{forward_range}@ && - is_reference_v> { + is_reference_v> && + @\libconcept{input_range}@> { return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; } @@ -6948,10 +7050,11 @@ return @\exposid{sentinel}@<@\exposconcept{simple-view}@ && @\exposconcept{simple-view}@>{*this}; } constexpr auto end() const - requires @\libconcept{input_range}@ && @\libconcept{forward_range}@ && - is_reference_v> { + requires @\libconcept{forward_range}@ && @\libconcept{forward_range}@ && + is_reference_v> && + @\libconcept{input_range}@> { using InnerConstRng = range_reference_t; - if constexpr (@\libconcept{forward_range}@ && @\libconcept{forward_range}@ && + if constexpr (@\libconcept{forward_range}@ && @\libconcept{common_range}@ && @\libconcept{common_range}@) return @\exposid{iterator}@{*this, ranges::end(@\exposid{base_}@)}; else @@ -6969,7 +7072,7 @@ \end{codeblock} \begin{itemdecl} -constexpr join_with_view(V base, Pattern pattern); +constexpr explicit join_with_view(V base, Pattern pattern); \end{itemdecl} \begin{itemdescr} @@ -6983,7 +7086,7 @@ template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> -constexpr join_with_view(R&& r, range_value_t<@\exposid{InnerRng}@> e); +constexpr explicit join_with_view(R&& r, range_value_t<@\exposid{InnerRng}@> e); \end{itemdecl} \begin{itemdescr} @@ -7014,12 +7117,18 @@ static constexpr bool @\exposid{ref-is-glvalue}@ = is_reference_v<@\exposid{InnerBase}@>; // \expos @\exposid{Parent}@* @\exposid{parent_}@ = nullptr; // \expos - @\exposid{OuterIter}@ @\exposid{outer_it_}@ = @\exposid{OuterIter}@(); // \expos + @\exposid{OuterIter}@ @\exposid{outer_it_}@ = @\exposid{OuterIter}@(); // \expos, present only + // if \exposid{Base} models \libconcept{forward_range} variant<@\exposid{PatternIter}@, @\exposid{InnerIter}@> @\exposid{inner_it_}@; // \expos - constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, iterator_t<@\exposid{Base}@> outer); // \expos - constexpr auto&& @\exposid{update-inner}@(const @\exposid{OuterIter}@&); // \expos - constexpr auto&& @\exposid{get-inner}@(const @\exposid{OuterIter}@&); // \expos + constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{OuterIter}@ outer) + requires @\libconcept{forward_range}@<@\exposid{Base}@>; // \expos + constexpr explicit @\exposid{iterator}@(@\exposid{Parent}@& parent) + requires (!@\libconcept{forward_range}@<@\exposid{Base}@>); // \expos + constexpr @\exposid{OuterIter}@& @\exposid{outer}@(); // \expos + constexpr const @\exposid{OuterIter}@& @\exposid{outer}@() const; // \expos + constexpr auto& @\exposid{update-inner}@(); // \expos + constexpr auto& @\exposid{get-inner}@(); // \expos constexpr void @\exposid{satisfy}@(); // \expos public: @@ -7028,7 +7137,7 @@ using value_type = @\seebelow@; using difference_type = @\seebelow@; - @\exposid{iterator}@() requires @\libconcept{default_initializable}@<@\exposid{OuterIter}@> = default; + @\exposid{iterator}@() = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@, @\exposid{OuterIter}@> && @\libconcept{convertible_to}@, @\exposid{InnerIter}@> && @@ -7050,7 +7159,7 @@ @\exposconcept{bidirectional-common}@<@\exposid{InnerBase}@> && @\exposconcept{bidirectional-common}@<@\exposid{PatternBase}@>; friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposid{ref-is-glvalue}@ && @\libconcept{equality_comparable}@<@\exposid{OuterIter}@> && + requires @\exposid{ref-is-glvalue}@ && @\libconcept{forward_range}@<@\exposid{Base}@> && @\libconcept{equality_comparable}@<@\exposid{InnerIter}@>; friend constexpr decltype(auto) iter_move(const @\exposid{iterator}@& x) { @@ -7140,7 +7249,19 @@ \end{codeblock} \begin{itemdecl} -constexpr auto&& @\exposid{update-inner}@(const @\exposid{OuterIter}@& x); +constexpr @\exposid{OuterIter}@& @\exposid{outer}@(); +constexpr const @\exposid{OuterIter}@& @\exposid{outer}@() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{outer_it_} if \exposid{Base} models \libconcept{forward_range}; +otherwise, \tcode{*\exposid{parent_}->\exposid{outer_it_}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto& @\exposid{update-inner}@(); \end{itemdecl} \begin{itemdescr} @@ -7149,14 +7270,14 @@ Equivalent to: \begin{codeblock} if constexpr (@\exposid{ref-is-glvalue}@) - return *x; + return @\exposid{as-lvalue}@(*@\exposid{outer}@()); else - return @\exposid{parent_}@->@\exposid{inner_}@.@\exposid{emplace-deref}@(x); + return @\exposid{parent_}@->@\exposid{inner_}@.@\exposid{emplace-deref}@(@\exposid{outer}@()); \end{codeblock} \end{itemdescr} \begin{itemdecl} -constexpr auto&& @\exposid{get-inner}@(const @\exposid{OuterIter}@& x); +constexpr auto& @\exposid{get-inner}@(); \end{itemdecl} \begin{itemdescr} @@ -7165,7 +7286,7 @@ Equivalent to: \begin{codeblock} if constexpr (@\exposid{ref-is-glvalue}@) - return *x; + return @\exposid{as-lvalue}@(*@\exposid{outer}@()); else return *@\exposid{parent_}@->@\exposid{inner_}@; \end{codeblock} @@ -7184,13 +7305,11 @@ if (@\exposid{inner_it_}@.index() == 0) { if (std::get<0>(@\exposid{inner_it_}@) != ranges::end(@\exposid{parent_}@->@\exposid{pattern_}@)) break; - auto&& inner = @\exposid{update-inner}@(@\exposid{outer_it_}@); - @\exposid{inner_it_}@.emplace<1>(ranges::begin(inner)); + @\exposid{inner_it_}@.emplace<1>(ranges::begin(@\exposid{update-inner}@())); } else { - auto&& inner = @\exposid{get-inner}@(@\exposid{outer_it_}@); - if (std::get<1>(@\exposid{inner_it_}@) != ranges::end(inner)) + if (std::get<1>(@\exposid{inner_it_}@) != ranges::end(@\exposid{get-inner}@())) break; - if (++@\exposid{outer_it_}@ == ranges::end(@\exposid{parent_}@->@\exposid{base_}@)) { + if (++@\exposid{outer}@() == ranges::end(@\exposid{parent_}@->@\exposid{base_}@)) { if constexpr (@\exposid{ref-is-glvalue}@) @\exposid{inner_it_}@.emplace<0>(); break; @@ -7207,19 +7326,22 @@ \end{itemdescr} \begin{itemdecl} -constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, iterator_t<@\exposid{Base}@> outer); +constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{OuterIter}@ outer) + requires @\libconcept{forward_range}@<@\exposid{Base}@>; +constexpr explicit @\exposid{iterator}@(@\exposid{Parent}@& parent) + requires (!@\libconcept{forward_range}@<@\exposid{Base}@>); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \exposid{parent_} with \tcode{addressof(parent)} and +Initializes \exposid{parent_} with \tcode{addressof(parent)}. +For the first overload, also initializes \exposid{outer_it_} with \tcode{std::move(outer)}. Then, equivalent to: \begin{codeblock} -if (@\exposid{outer_it_}@ != ranges::end(@\exposid{parent_}@->@\exposid{base_}@)) { - auto&& inner = @\exposid{update-inner}@(@\exposid{outer_it_}@); - @\exposid{inner_it_}@.emplace<1>(ranges::begin(inner)); +if (@\exposid{outer}@() != ranges::end(@\exposid{parent_}@->@\exposid{base_}@)) { + @\exposid{inner_it_}@.emplace<1>(ranges::begin(@\exposid{update-inner}@())); @\exposidnc{satisfy}@(); } \end{codeblock} @@ -7245,6 +7367,12 @@ else @\exposid{inner_it_}@.emplace<1>(std::get<1>(std::move(i.@\exposid{inner_it_}@))); \end{codeblock} + +\pnum +\begin{note} +\tcode{Const} can only be \tcode{true} +when \exposid{Base} models \libconcept{forward_range}. +\end{note} \end{itemdescr} \begin{itemdecl} @@ -7362,7 +7490,7 @@ \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposid{ref-is-glvalue}@ && @\libconcept{equality_comparable}@<@\exposid{OuterIter}@> && + requires @\exposid{ref-is-glvalue}@ && @\libconcept{forward_range}@<@\exposid{Base}@> && @\libconcept{equality_comparable}@<@\exposid{InnerIter}@>; \end{itemdecl} @@ -7432,7 +7560,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return x.\exposid{outer_it_} == y.\exposid{end_};} +Equivalent to: \tcode{return x.\exposid{outer}() == y.\exposid{end_};} \end{itemdescr} \rSec2[range.lazy.split]{Lazy split view} @@ -7491,7 +7619,7 @@ Pattern @\exposid{pattern_}@ = Pattern(); // \expos @\exposidnc{non-propagating-cache}@> @\exposid{current_}@; // \expos, present only - // if \tcode{!\libconcept{forward_range}} + // if \tcode{\libconcept{forward_range}} is \tcode{false} // \ref{range.lazy.split.outer}, class template \tcode{lazy_split_view::\exposid{outer-iterator}} template struct @\exposidnc{outer-iterator}@; // \expos @@ -7502,12 +7630,12 @@ public: lazy_split_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr lazy_split_view(V base, Pattern pattern); + constexpr explicit lazy_split_view(V base, Pattern pattern); template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> - constexpr lazy_split_view(R&& r, range_value_t e); + constexpr explicit lazy_split_view(R&& r, range_value_t e); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -7550,7 +7678,7 @@ \indexlibraryctor{lazy_split_view}% \begin{itemdecl} -constexpr lazy_split_view(V base, Pattern pattern); +constexpr explicit lazy_split_view(V base, Pattern pattern); \end{itemdecl} \begin{itemdescr} @@ -7565,7 +7693,7 @@ template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> -constexpr lazy_split_view(R&& r, range_value_t e); +constexpr explicit lazy_split_view(R&& r, range_value_t e); \end{itemdecl} \begin{itemdescr} @@ -8018,8 +8146,8 @@ \begin{example} \begin{codeblock} string str{"the quick brown fox"}; -for (string_view word : views::split(str, ' ')) { - cout << word << '*'; +for (auto word : views::split(str, ' ')) { + cout << string_view(word) << '*'; } // The above prints \tcode{the*quick*brown*fox*} \end{codeblock} @@ -8046,12 +8174,12 @@ public: split_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; - constexpr split_view(V base, Pattern pattern); + constexpr explicit split_view(V base, Pattern pattern); template<@\libconcept{forward_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> - constexpr split_view(R&& r, range_value_t e); + constexpr explicit split_view(R&& r, range_value_t e); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } @@ -8079,7 +8207,7 @@ \end{codeblock} \begin{itemdecl} -constexpr split_view(V base, Pattern pattern); +constexpr explicit split_view(V base, Pattern pattern); \end{itemdecl} \begin{itemdescr} @@ -8094,7 +8222,7 @@ template<@\libconcept{forward_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> -constexpr split_view(R&& r, range_value_t e); +constexpr explicit split_view(R&& r, range_value_t e); \end{itemdecl} \begin{itemdescr} @@ -8625,11 +8753,20 @@ then \tcode{views::all(E)}. \item Otherwise, +if \tcode{U} denotes \tcode{empty_view} +for some type \tcode{X}, then \tcode{auto(views::empty)}. +\item +Otherwise, if \tcode{U} denotes \tcode{span} for some type \tcode{X} and some extent \tcode{Extent}, then \tcode{span(E)}. \item Otherwise, +if \tcode{U} denotes \tcode{ref_view} for some type \tcode{X} and +\tcode{const X} models \libconcept{constant_range}, +then \tcode{ref_view(static_cast(E.base()))}. +\item +Otherwise, if \tcode{E} is an lvalue, \tcode{const U} models \libconcept{constant_range}, and \tcode{U} does not model \libconcept{view}, @@ -9341,192 +9478,737 @@ Equivalent to: \tcode{return x.\exposid{end_} - y.\exposid{current_};} \end{itemdescr} -\rSec2[range.zip]{Zip view} +\rSec2[range.enumerate]{Enumerate view} -\rSec3[range.zip.overview]{Overview} +\rSec3[range.enumerate.overview]{Overview} \pnum -\indexlibraryglobal{zip_view}% -\tcode{zip_view} takes any number of views and -produces a view of tuples of references -to the corresponding elements of the constituent views. +\indexlibraryglobal{enumerate_view}% +\tcode{enumerate_view} is a view whose +elements represent both the position and value from +a sequence of elements. \pnum -\indexlibrarymember{zip}{views}% -The name \tcode{views::zip} denotes -a customization point object\iref{customization.point.object}. -Given a pack of subexpressions \tcode{Es...}, -the expression \tcode{views::zip(Es...)} is expression-equivalent to -\begin{itemize} -\item -\tcode{auto(views::empty>)} -if \tcode{Es} is an empty pack, -\item -otherwise, \tcode{zip_view...>(Es...)}. -\end{itemize} - +\indexlibrarymember{enumerate}{views}% +The name \tcode{views::enumerate} denotes a range adaptor object. +Given a subexpression \tcode{E}, +the expression \tcode{views::enumerate(E)} is expression-equivalent to +\tcode{enumerate_view>(E)}. \begin{example} \begin{codeblock} -vector v = {1, 2}; -list l = {'a', 'b', 'c'}; - -auto z = views::zip(v, l); -range_reference_t f = z.front(); // \tcode{f} is a \tcode{tuple} - // that refers to the first element of \tcode{v} and \tcode{l} - -for (auto&& [x, y] : z) { - cout << '(' << x << ", " << y << ") "; // prints \tcode{(1, a) (2, b)} -} +vector vec{ 1, 2, 3 }; +for (auto [index, value] : views::enumerate(vec)) + cout << index << ":" << value << ' '; // prints \tcode{0:1 1:2 2:3} \end{codeblock} \end{example} -\rSec3[range.zip.view]{Class template \tcode{zip_view}} +\rSec3[range.enumerate.view]{Class template \tcode{enumerate_view}} -\indexlibrarymember{begin}{zip_view}% -\indexlibrarymember{end}{zip_view}% -\indexlibrarymember{size}{zip_view}% +\indexlibrarymember{begin}{enumerate_view}% +\indexlibrarymember{end}{enumerate_view}% +\indexlibrarymember{size}{enumerate_view}% \begin{codeblock} namespace std::ranges { - template - concept @\defexposconcept{zip-is-common}@ = // \expos - (sizeof...(Rs) == 1 && (@\libconcept{common_range}@ && ...)) || - (!(@\libconcept{bidirectional_range}@ && ...) && (@\libconcept{common_range}@ && ...)) || - ((@\libconcept{random_access_range}@ && ...) && (@\libconcept{sized_range}@ && ...)); - - template<@\libconcept{input_range}@... Views> - requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) - class zip_view : public view_interface> { - tuple @\exposid{views_}@; // \expos + template<@\libconcept{view}@ V> + requires @\exposconcept{range-with-movable-references}@ + class enumerate_view : public view_interface> { + V @\exposidnc{base_}@ = V(); // \expos - // \ref{range.zip.iterator}, class template \tcode{zip_view::\exposid{iterator}} - template class @\exposidnc{iterator}@; // \expos + // \ref{range.enumerate.iterator}, class template \tcode{enumerate_view::\exposid{iterator}} + template + class @\exposidnc{iterator}@; // \expos - // \ref{range.zip.sentinel}, class template \tcode{zip_view::\exposid{sentinel}} - template class @\exposidnc{sentinel}@; // \expos + // \ref{range.enumerate.sentinel}, class template \tcode{enumerate_view::\exposid{sentinel}} + template + class @\exposidnc{sentinel}@; // \expos public: - zip_view() = default; - constexpr explicit zip_view(Views... views); + constexpr enumerate_view() requires @\libconcept{default_initializable}@ = default; + constexpr explicit enumerate_view(V base); - constexpr auto begin() requires (!(@\exposconcept{simple-view}@ && ...)) { - return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::begin, @\exposid{views_}@)); - } - constexpr auto begin() const requires (@\libconcept{range}@ && ...) { - return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::begin, @\exposid{views_}@)); - } + constexpr auto begin() requires (!@\exposconcept{simple-view}@) + { return @\exposid{iterator}@(ranges::begin(@\exposid{base_}@), 0); } + constexpr auto begin() const requires @\exposconcept{range-with-movable-references}@ + { return @\exposid{iterator}@(ranges::begin(@\exposid{base_}@), 0); } - constexpr auto end() requires (!(@\exposconcept{simple-view}@ && ...)) { - if constexpr (!@\exposconcept{zip-is-common}@) { - return @\exposid{sentinel}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); - } else if constexpr ((@\libconcept{random_access_range}@ && ...)) { - return begin() + iter_difference_t<@\exposid{iterator}@>(size()); - } else { - return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); - } + constexpr auto end() requires (!@\exposconcept{simple-view}@) { + if constexpr (@\libconcept{common_range}@ && @\libconcept{sized_range}@) + return @\exposid{iterator}@(ranges::end(@\exposid{base_}@), ranges::distance(@\exposid{base_}@)); + else + return @\exposid{sentinel}@(ranges::end(@\exposid{base_}@)); } - - constexpr auto end() const requires (@\libconcept{range}@ && ...) { - if constexpr (!@\exposconcept{zip-is-common}@) { - return @\exposid{sentinel}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); - } else if constexpr ((@\libconcept{random_access_range}@ && ...)) { - return begin() + iter_difference_t<@\exposid{iterator}@>(size()); - } else { - return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); - } + constexpr auto end() const requires @\exposconcept{range-with-movable-references}@ { + if constexpr (@\libconcept{common_range}@ && @\libconcept{sized_range}@) + return @\exposid{iterator}@(ranges::end(@\exposid{base_}@), ranges::distance(@\exposid{base_}@)); + else + return @\exposid{sentinel}@(ranges::end(@\exposid{base_}@)); } - constexpr auto size() requires (@\libconcept{sized_range}@ && ...); - constexpr auto size() const requires (@\libconcept{sized_range}@ && ...); + constexpr auto size() + requires @\libconcept{sized_range}@ + { return ranges::size(@\exposid{base_}@); } + constexpr auto size() const + requires @\libconcept{sized_range}@ + { return ranges::size(@\exposid{base_}@); } + + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } }; - template - zip_view(Rs&&...) -> zip_view...>; + template + enumerate_view(R&&) -> enumerate_view>; } \end{codeblock} -\pnum -Two \tcode{zip_view} objects have the same underlying sequence if and only if -the corresponding elements of \exposid{views_} are equal\iref{concepts.equality} -and have the same underlying sequence. -\begin{note} -In particular, comparison of iterators obtained from \tcode{zip_view} objects -that do not have the same underlying sequence -is not required to produce meaningful results\iref{iterator.concept.forward}. -\end{note} - -\begin{itemdecl} -constexpr explicit zip_view(Views... views); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \exposid{views_} with \tcode{std::move(views)...}. -\end{itemdescr} - \begin{itemdecl} -constexpr auto size() requires (@\libconcept{sized_range}@ && ...); -constexpr auto size() const requires (@\libconcept{sized_range}@ && ...); +constexpr explicit enumerate_view(V base); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: -\begin{codeblock} -return apply([](auto... sizes) { - using CT = @\exposid{make-unsigned-like-t}@>; - return ranges::min({CT(sizes)...}); -}, @\exposid{tuple-transform}@(ranges::size, @\exposid{views_}@)); -\end{codeblock} +Initializes \exposid{base_} with \tcode{std::move(base)}. \end{itemdescr} -\rSec3[range.zip.iterator]{Class template \tcode{zip_view::\exposid{iterator}}} +\rSec3[range.enumerate.iterator]{Class template \tcode{enumerate_view::\exposid{iterator}}} +\indexlibraryglobal{enumerate_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { - template - concept @\defexposconceptnc{all-random-access}@ = // \expos - (@\libconcept{random_access_range}@<@\exposid{maybe-const}@> && ...); - template - concept @\defexposconceptnc{all-bidirectional}@ = // \expos - (@\libconcept{bidirectional_range}@<@\exposid{maybe-const}@> && ...); - template - concept @\defexposconceptnc{all-forward}@ = // \expos - (@\libconcept{forward_range}@<@\exposid{maybe-const}@> && ...); - - template<@\libconcept{input_range}@... Views> - requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) + template<@\libconcept{view}@ V> + requires @\exposconcept{range-with-movable-references}@ template - class zip_view::@\exposid{iterator}@ { - tuple>...> @\exposid{current_}@;@\itcorr[-1]@ // \expos - constexpr explicit @\exposidnc{iterator}@(tuple>...>); - // \expos + class enumerate_view::@\exposid{iterator}@ { + using @\exposidnc{Base}@ = @\exposidnc{maybe-const}@; // \expos + public: - using iterator_category = input_iterator_tag; // not always present - using iterator_concept = @\seebelow@; - using value_type = tuple>...>; - using difference_type = common_type_t>...>; + using iterator_category = input_iterator_tag; + using iterator_concept = @\seebelow@; + using difference_type = range_difference_t<@\exposid{Base}@>; + using value_type = tuple>; - @\exposid{iterator}@() = default; + private: + using @\exposidnc{reference-type}@ = // \expos + tuple>; + iterator_t<@\exposidnc{Base}@> @\exposidnc{current_}@ = iterator_t<@\exposidnc{Base}@>(); // \expos + difference_type @\exposidnc{pos_}@ = 0; // \expos + + constexpr explicit + @\exposidnc{iterator}@(iterator_t<@\exposidnc{Base}@> current, difference_type pos); // \expos + + public: + @\exposid{iterator}@() requires @\libconcept{default_initializable}@> = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) - requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; + + constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; + constexpr iterator_t<@\exposid{Base}@> base() &&; + + constexpr difference_type index() const noexcept; + + constexpr auto operator*() const { + return @\exposid{reference-type}@(@\exposid{pos_}@, *@\exposid{current_}@); + } - constexpr auto operator*() const; constexpr @\exposid{iterator}@& operator++(); constexpr void operator++(int); - constexpr @\exposid{iterator}@ operator++(int) requires @\exposconcept{all-forward}@; + constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{Base}@>; - constexpr @\exposid{iterator}@& operator--() requires @\exposconcept{all-bidirectional}@; - constexpr @\exposid{iterator}@ operator--(int) requires @\exposconcept{all-bidirectional}@; + constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; + constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; constexpr @\exposid{iterator}@& operator+=(difference_type x) - requires @\exposconcept{all-random-access}@; + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; constexpr @\exposid{iterator}@& operator-=(difference_type x) - requires @\exposconcept{all-random-access}@; + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; constexpr auto operator[](difference_type n) const - requires @\exposconcept{all-random-access}@; + requires @\libconcept{random_access_range}@<@\exposid{Base}@> + { return @\exposid{reference-type}@(@\exposid{pos_}@ + n, @\exposid{current_}@[n]); } + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) noexcept; + friend constexpr strong_ordering operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) noexcept; + + friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr @\exposid{iterator}@ operator+(difference_type x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); + + friend constexpr auto iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@)) && + is_nothrow_move_constructible_v>) { + return tuple>(i.@\exposid{pos_}@, ranges::iter_move(i.@\exposid{current_}@)); + } + }; +} +\end{codeblock} + +\pnum +The member \grammarterm{typedef-name} +\tcode{\exposid{iterator}::iterator_concept} +is defined as follows: +\begin{itemize} +\item +If \exposid{Base} models \libconcept{random_access_range}, +then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, if \exposid{Base} models \libconcept{bidirectional_range}, +then \tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. +\item +Otherwise, if \exposid{Base} models \libconcept{forward_range}, +then \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\indexlibraryctor{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current, difference_type pos); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(current)} and +\exposid{pos_} with \tcode{pos}. +\end{itemdescr} + +\indexlibraryctor{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})} and +\exposid{pos_} with \tcode{i.\exposid{pos_}}. +\end{itemdescr} + +\indexlibrarymember{base}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{current_};} +\end{itemdescr} + +\indexlibrarymember{base}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr iterator_t<@\exposid{Base}@> base() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return std::move(\exposid{current_});} +\end{itemdescr} + +\indexlibrarymember{index}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr difference_type index() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{pos_};} +\end{itemdescr} + +\indexlibrarymember{operator++}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +++@\exposid{current_}@; +++@\exposid{pos_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator++}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{++*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto temp = *this; +++*this; +return temp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +--@\exposid{current_}@; +--@\exposid{pos_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto temp = *this; +--*this; +return temp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+=}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator+=(difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{current_}@ += n; +@\exposid{pos_}@ += n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-=}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator-=(difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{current_}@ -= n; +@\exposid{pos_}@ -= n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator==}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{pos_} == y.\exposid{pos_};} +\end{itemdescr} + +\indexlibrarymember{operator<=>}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr strong_ordering operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{pos_} <=> y.\exposid{pos_};} +\end{itemdescr} + +\indexlibrarymember{operator+}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto temp = x; +temp += y; +return temp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(difference_type x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return y + x;} +\end{itemdescr} + +\indexlibrarymember{operator-}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto temp = x; +temp -= y; +return temp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-}{enumerate_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{pos_} - y.\exposid{pos_};} +\end{itemdescr} + +\rSec3[range.enumerate.sentinel]{Class template \tcode{enumerate_view::\exposid{sentinel}}} + +\indexlibraryglobal{enumerate_view::\exposid{sentinel}}% +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{view}@ V> + requires @\exposconcept{range-with-movable-references}@ + template + class enumerate_view::@\exposid{sentinel}@ { + using @\exposidnc{Base}@ = @\exposidnc{maybe-const}@; // \expos + sentinel_t<@\exposidnc{Base}@> @\exposidnc{end_}@ = sentinel_t<@\exposidnc{Base}@>(); // \expos + constexpr explicit @\exposidnc{sentinel}@(sentinel_t<@\exposidnc{Base}@> end); // \expos + + public: + @\exposid{sentinel}@() = default; + constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ other) + requires Const && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; + + constexpr sentinel_t<@\exposid{Base}@> base() const; + + template + requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); + + template + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> + friend constexpr range_difference_t<@\exposid{maybe-const}@> + operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); + + template + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> + friend constexpr range_difference_t<@\exposid{maybe-const}@> + operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y); + }; +} +\end{codeblock} + +\indexlibraryctor{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +constexpr explicit @\exposid{sentinel}@(sentinel_t<@\exposid{Base}@> end); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{end_} with \tcode{std::move(end)}. +\end{itemdescr} + +\indexlibraryctor{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ other) + requires Const && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{end_} with \tcode{std::move(other.\exposid{end_})}. +\end{itemdescr} + +\indexlibrarymember{base}{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +constexpr sentinel_t<@\exposid{Base}@> base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{end_};} +\end{itemdescr} + +\indexlibrarymember{operator==}{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +template + requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} == y.\exposid{end_};} +\end{itemdescr} + +\indexlibrarymember{operator-}{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +template + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> +friend constexpr range_difference_t<@\exposid{maybe-const}@> + operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} - y.\exposid{end_};} +\end{itemdescr} + +\indexlibrarymember{operator-}{enumerate_view::\exposid{sentinel}}% +\begin{itemdecl} +template + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> +friend constexpr range_difference_t<@\exposid{maybe-const}@> + operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{end_} - y.\exposid{current_};} +\end{itemdescr} + +\rSec2[range.zip]{Zip view} + +\rSec3[range.zip.overview]{Overview} + +\pnum +\indexlibraryglobal{zip_view}% +\tcode{zip_view} takes any number of views and +produces a view of tuples of references +to the corresponding elements of the constituent views. + +\pnum +\indexlibrarymember{zip}{views}% +The name \tcode{views::zip} denotes +a customization point object\iref{customization.point.object}. +Given a pack of subexpressions \tcode{Es...}, +the expression \tcode{views::zip(Es...)} is expression-equivalent to +\begin{itemize} +\item +\tcode{auto(views::empty>)} +if \tcode{Es} is an empty pack, +\item +otherwise, \tcode{zip_view...>(Es...)}. +\end{itemize} + +\begin{example} +\begin{codeblock} +vector v = {1, 2}; +list l = {'a', 'b', 'c'}; + +auto z = views::zip(v, l); +range_reference_t f = z.front(); // \tcode{f} is a \tcode{tuple} + // that refers to the first element of \tcode{v} and \tcode{l} + +for (auto&& [x, y] : z) { + cout << '(' << x << ", " << y << ") "; // prints \tcode{(1, a) (2, b)} +} +\end{codeblock} +\end{example} + +\rSec3[range.zip.view]{Class template \tcode{zip_view}} + +\indexlibrarymember{begin}{zip_view}% +\indexlibrarymember{end}{zip_view}% +\indexlibrarymember{size}{zip_view}% +\begin{codeblock} +namespace std::ranges { + template + concept @\defexposconcept{zip-is-common}@ = // \expos + (sizeof...(Rs) == 1 && (@\libconcept{common_range}@ && ...)) || + (!(@\libconcept{bidirectional_range}@ && ...) && (@\libconcept{common_range}@ && ...)) || + ((@\libconcept{random_access_range}@ && ...) && (@\libconcept{sized_range}@ && ...)); + + template<@\libconcept{input_range}@... Views> + requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) + class zip_view : public view_interface> { + tuple @\exposid{views_}@; // \expos + + // \ref{range.zip.iterator}, class template \tcode{zip_view::\exposid{iterator}} + template class @\exposidnc{iterator}@; // \expos + + // \ref{range.zip.sentinel}, class template \tcode{zip_view::\exposid{sentinel}} + template class @\exposidnc{sentinel}@; // \expos + + public: + zip_view() = default; + constexpr explicit zip_view(Views... views); + + constexpr auto begin() requires (!(@\exposconcept{simple-view}@ && ...)) { + return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::begin, @\exposid{views_}@)); + } + constexpr auto begin() const requires (@\libconcept{range}@ && ...) { + return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::begin, @\exposid{views_}@)); + } + + constexpr auto end() requires (!(@\exposconcept{simple-view}@ && ...)) { + if constexpr (!@\exposconcept{zip-is-common}@) { + return @\exposid{sentinel}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); + } else if constexpr ((@\libconcept{random_access_range}@ && ...)) { + return begin() + iter_difference_t<@\exposid{iterator}@>(size()); + } else { + return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); + } + } + + constexpr auto end() const requires (@\libconcept{range}@ && ...) { + if constexpr (!@\exposconcept{zip-is-common}@) { + return @\exposid{sentinel}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); + } else if constexpr ((@\libconcept{random_access_range}@ && ...)) { + return begin() + iter_difference_t<@\exposid{iterator}@>(size()); + } else { + return @\exposid{iterator}@(@\exposid{tuple-transform}@(ranges::end, @\exposid{views_}@)); + } + } + + constexpr auto size() requires (@\libconcept{sized_range}@ && ...); + constexpr auto size() const requires (@\libconcept{sized_range}@ && ...); + }; + + template + zip_view(Rs&&...) -> zip_view...>; +} +\end{codeblock} + +\pnum +Two \tcode{zip_view} objects have the same underlying sequence if and only if +the corresponding elements of \exposid{views_} are equal\iref{concepts.equality} +and have the same underlying sequence. +\begin{note} +In particular, comparison of iterators obtained from \tcode{zip_view} objects +that do not have the same underlying sequence +is not required to produce meaningful results\iref{iterator.concept.forward}. +\end{note} + +\begin{itemdecl} +constexpr explicit zip_view(Views... views); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{views_} with \tcode{std::move(views)...}. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto size() requires (@\libconcept{sized_range}@ && ...); +constexpr auto size() const requires (@\libconcept{sized_range}@ && ...); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return apply([](auto... sizes) { + using CT = @\exposid{make-unsigned-like-t}@>; + return ranges::min({CT(sizes)...}); +}, @\exposid{tuple-transform}@(ranges::size, @\exposid{views_}@)); +\end{codeblock} +\end{itemdescr} + +\rSec3[range.zip.iterator]{Class template \tcode{zip_view::\exposid{iterator}}} + +\begin{codeblock} +namespace std::ranges { + template + concept @\defexposconceptnc{all-random-access}@ = // \expos + (@\libconcept{random_access_range}@<@\exposid{maybe-const}@> && ...); + template + concept @\defexposconceptnc{all-bidirectional}@ = // \expos + (@\libconcept{bidirectional_range}@<@\exposid{maybe-const}@> && ...); + template + concept @\defexposconceptnc{all-forward}@ = // \expos + (@\libconcept{forward_range}@<@\exposid{maybe-const}@> && ...); + + template<@\libconcept{input_range}@... Views> + requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) + template + class zip_view::@\exposid{iterator}@ { + tuple>...> @\exposid{current_}@;@\itcorr[-1]@ // \expos + constexpr explicit @\exposidnc{iterator}@(tuple>...>); + // \expos + public: + using iterator_category = input_iterator_tag; // not always present + using iterator_concept = @\seebelow@; + using value_type = tuple>...>; + using difference_type = common_type_t>...>; + + @\exposid{iterator}@() = default; + constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) + requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); + + constexpr auto operator*() const; + constexpr @\exposid{iterator}@& operator++(); + constexpr void operator++(int); + constexpr @\exposid{iterator}@ operator++(int) requires @\exposconcept{all-forward}@; + + constexpr @\exposid{iterator}@& operator--() requires @\exposconcept{all-bidirectional}@; + constexpr @\exposid{iterator}@ operator--(int) requires @\exposconcept{all-bidirectional}@; + + constexpr @\exposid{iterator}@& operator+=(difference_type x) + requires @\exposconcept{all-random-access}@; + constexpr @\exposid{iterator}@& operator-=(difference_type x) + requires @\exposconcept{all-random-access}@; + + constexpr auto operator[](difference_type n) const + requires @\exposconcept{all-random-access}@; friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires (@\libconcept{equality_comparable}@>> && ...); @@ -10565,6 +11247,9 @@ adjacent_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit adjacent_view(V base); + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + constexpr auto begin() requires (!@\exposconcept{simple-view}@) { return @\exposid{iterator}@(ranges::begin(@\exposid{base_}@), ranges::end(@\exposid{base_}@)); } @@ -11206,6 +11891,9 @@ adjacent_transform_view() = default; constexpr explicit adjacent_transform_view(V base, F fun); + constexpr V base() const & requires @\libconcept{copy_constructible}@<@\exposid{InnerView}@> { return @\exposid{inner_}@.base(); } + constexpr V base() && { return std::move(@\exposid{inner_}@).base(); } + constexpr auto begin() { return @\exposid{iterator}@(*this, @\exposid{inner_}@.begin()); } @@ -12013,6 +12701,13 @@ requires @\libconcept{sized_sentinel_for}@, iterator_t>; friend constexpr difference_type operator-(const @\exposid{inner-iterator}@& x, default_sentinel_t y) requires @\libconcept{sized_sentinel_for}@, iterator_t>; + + friend constexpr range_rvalue_reference_t iter_move(const @\exposid{inner-iterator}@& i) + noexcept(noexcept(ranges::iter_move(*i.@\exposid{parent_}@->@\exposid{current_}@))); + + friend constexpr void iter_swap(const @\exposid{inner-iterator}@& x, const @\exposid{inner-iterator}@& y) + noexcept(noexcept(ranges::iter_swap(*x.@\exposid{parent_}@->@\exposid{current_}@, *y.@\exposid{parent_}@->@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; }; } \end{codeblock} @@ -12119,6 +12814,29 @@ Equivalent to: \tcode{return -(y - x);} \end{itemdescr} +\begin{itemdecl} +friend constexpr range_rvalue_reference_t iter_move(const @\exposid{inner-iterator}@& i) + noexcept(noexcept(ranges::iter_move(*i.@\exposid{parent_}@->@\exposid{current_}@))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::iter_move(*i.\exposid{parent_}->\exposid{current_});} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr void iter_swap(const @\exposid{inner-iterator}@& x, const @\exposid{inner-iterator}@& y) + noexcept(noexcept(ranges::iter_swap(*x.@\exposid{parent_}@->@\exposid{current_}@, *y.@\exposid{parent_}@->@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{ranges::iter_swap(*x.\exposid{parent_}->\exposid{current_}, *y.\exposid{parent_}->\exposid{current_});} +\end{itemdescr} + \rSec3[range.chunk.view.fwd]{Class template \tcode{chunk_view} for forward ranges} \indexlibrarymember{begin}{chunk_view}% @@ -12434,7 +13152,8 @@ Equivalent to: \begin{codeblock} if (x > 0) { - @\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{n_}@ * x, @\exposid{end_}@); + ranges::advance(@\exposid{current_}@, @\exposid{n_}@ * (x - 1)); + @\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{n_}@, @\exposid{end_}@); } else if (x < 0) { ranges::advance(@\exposid{current_}@, @\exposid{n_}@ * x + @\exposid{missing_}@); @\exposid{missing_}@ = 0; @@ -12672,6 +13391,9 @@ public: constexpr explicit slide_view(V base, range_difference_t n); + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + constexpr auto begin() requires (!(@\exposconcept{simple-view}@ && @\exposconcept{slide-caches-nothing}@)); constexpr auto begin() const requires @\exposconcept{slide-caches-nothing}@; @@ -13994,7 +14716,8 @@ Equivalent to: \begin{codeblock} if (n > 0) { - @\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{stride_}@ * n, @\exposid{end_}@); + ranges::advance(@\exposid{current_}@, @\exposid{stride_}@ * (n - 1)); + @\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{stride_}@, @\exposid{end_}@); } else if (n < 0) { ranges::advance(@\exposid{current_}@, @\exposid{stride_}@ * n + @\exposid{missing_}@); @\exposid{missing_}@ = 0; @@ -14458,7 +15181,7 @@ range_reference_t<@\exposid{maybe-const}@>...>; using difference_type = @\seebelow@; - @\exposid{iterator}@() requires @\libconcept{forward_range}@<@\exposid{maybe-const}@> = default; + @\exposid{iterator}@() = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && (@\libconcept{convertible_to}@, iterator_t> && @@ -14597,9 +15320,9 @@ Equivalent to: \begin{codeblock} auto& it = std::get(@\exposid{current_}@); -if (it == ranges::begin(std::get(@\exposid{parent_}@->@\exposid{bases_}@))) { - it = @\exposid{cartesian-common-arg-end}@(std::get(@\exposid{parent_}@->@\exposid{bases_}@)); - if constexpr (N > 0) { +if constexpr (N > 0) { + if (it == ranges::begin(std::get(@\exposid{parent_}@->@\exposid{bases_}@))) { + it = @\exposid{cartesian-common-arg-end}@(std::get(@\exposid{parent_}@->@\exposid{bases_}@)); @\exposid{prev}@(); } } @@ -15014,6 +15737,11 @@ // \ref{coro.generator.class}, class template \tcode{generator} template class generator; + + namespace pmr { + template + using generator = std::generator>; + } } \end{codeblock} diff --git a/source/regex.tex b/source/regex.tex index 1503118992..dcd432b3e1 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -1867,6 +1867,8 @@ int compare(const sub_match& s) const; int compare(const string_type& s) const; int compare(const value_type* s) const; + + void swap(sub_match& s) noexcept(@\seebelow@); }; } \end{codeblock} @@ -1952,6 +1954,31 @@ \tcode{str().compare(s)}. \end{itemdescr} +\indexlibrarymember{sub_match}{swap}% +\begin{itemdecl} +void swap(sub_match& s) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{BidirectionalIterator} meets +the \oldconcept{Swappable} requirements\iref{swappable.requirements}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +this->pair::swap(s); +std::swap(matched, s.matched); +\end{codeblock} + +\pnum +\remarks +The exception specification is equivalent to +\tcode{is_nothrow_swappable_v}. +\end{itemdescr} + \rSec2[re.submatch.op]{Non-member operators} \pnum @@ -2149,7 +2176,7 @@ using value_type = sub_match; using const_reference = const value_type&; using reference = value_type&; - using const_iterator = @{\impdef}@; + using const_iterator = @\impdefx{type of \tcode{match_results::const_iterator}}@; using iterator = const_iterator; using difference_type = typename iterator_traits::difference_type; @@ -2161,9 +2188,11 @@ // \ref{re.results.const}, construct/copy/destroy match_results() : match_results(Allocator()) {} - explicit match_results(const Allocator&); + explicit match_results(const Allocator& a); match_results(const match_results& m); + match_results(const match_results& m, const Allocator& a); match_results(match_results&& m) noexcept; + match_results(match_results&& m, const Allocator& a); match_results& operator=(const match_results& m); match_results& operator=(match_results&& m); ~match_results(); @@ -2232,6 +2261,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\effects +The stored \tcode{Allocator} value is constructed from \tcode{a}. + \pnum \ensures \tcode{ready()} returns \tcode{false}. @@ -2241,9 +2274,18 @@ \indexlibraryctor{match_results}% \begin{itemdecl} match_results(const match_results& m); +match_results(const match_results& m, const Allocator& a); \end{itemdecl} \begin{itemdescr} +\pnum +\effects +For the first form, +the stored \tcode{Allocator} value is obtained +as specified in \ref{container.reqmts}. +For the second form, +the stored \tcode{Allocator} value is constructed from \tcode{a}. + \pnum \ensures As specified in \tref{re.results.const}. @@ -2252,16 +2294,25 @@ \indexlibraryctor{match_results}% \begin{itemdecl} match_results(match_results&& m) noexcept; +match_results(match_results&& m, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects -The stored \tcode{Allocator} value is move constructed from \tcode{m.get_allocator()}. +For the first form, +the stored \tcode{Allocator} value is move constructed from \tcode{m.get_allocator()}. +For the second form, +the stored \tcode{Allocator} value is constructed from \tcode{a}. \pnum \ensures As specified in \tref{re.results.const}. + +\pnum +\throws +The second form throws nothing if +\tcode{a == m.get_allocator()} is \tcode{true}. \end{itemdescr} \indexlibrarymember{match_results}{operator=}% @@ -3213,6 +3264,7 @@ public: using regex_type = basic_regex; using iterator_category = forward_iterator_tag; + using iterator_concept = input_iterator_tag; using value_type = match_results; using difference_type = ptrdiff_t; using pointer = const value_type*; @@ -3483,6 +3535,7 @@ public: using regex_type = basic_regex; using iterator_category = forward_iterator_tag; + using iterator_concept = input_iterator_tag; using value_type = sub_match; using difference_type = ptrdiff_t; using pointer = const value_type*; diff --git a/source/statements.tex b/source/statements.tex index 9bcd85d5bc..aa9ae2bbbf 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -83,9 +83,9 @@ \pnum \indextext{\idxgram{condition}{s}!rules for}% -The rules for \grammarterm{condition}{s} apply both to -\grammarterm{selection-statement}{s} and to the \keyword{for} and \keyword{while} -statements\iref{stmt.iter}. +The rules for \grammarterm{condition}{s} apply both +to \grammarterm{selection-statement}{s}\iref{stmt.select} and +to the \keyword{for} and \keyword{while} statements\iref{stmt.iter}. A \grammarterm{condition} that is not an \grammarterm{expression} is a declaration\iref{dcl.dcl}. The \grammarterm{declarator} shall not @@ -268,7 +268,7 @@ \indextext{statement!\idxcode{if}} \pnum -If the condition\iref{stmt.select} yields \tcode{true} the first +If the condition\iref{stmt.pre} yields \tcode{true} the first substatement is executed. If the \keyword{else} part of the selection statement is present and the condition yields \tcode{false}, the second substatement is executed. If the first substatement is reached via a @@ -552,7 +552,7 @@ \pnum In the \keyword{while} statement the substatement is executed repeatedly -until the value of the condition\iref{stmt.select} becomes +until the value of the condition\iref{stmt.pre} becomes \tcode{false}. The test takes place before each execution of the substatement. @@ -630,7 +630,7 @@ re-evaluating \grammarterm{condition}. \begin{note} Thus the first statement specifies initialization for the loop; the -condition\iref{stmt.select} specifies a test, sequenced before each +condition\iref{stmt.pre} specifies a test, sequenced before each iteration, such that the loop is exited when the condition becomes \tcode{false}; the expression often specifies incrementing that is sequenced after each iteration. diff --git a/source/strings.tex b/source/strings.tex index 433abb6e66..ccc85dcf88 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -157,7 +157,7 @@ Copies correctly even where the ranges \tcode{[p,p+n)} and \tcode{[s,s+n)} overlap.\br \returns \tcode{s}. & linear \\ \rowsep \tcode{X::copy(s,p,n)} & \tcode{X::char_type*} & \expects -\tcode{p} not in \tcode{[s,s+n)}.\par +The ranges \range{p}{p+n} and \range{s}{s+n} do not overlap.\par \returns \tcode{s}.\br for each \tcode{i} in @@ -868,14 +868,10 @@ \item \tcode{is_same_v, charT>} is \tcode{true}, \item -\tcode{is_convertible_v} is \tcode{false}, +\tcode{is_convertible_v} is \tcode{false}, and \item \tcode{d.operator ::std::basic_string_view()} -is not a valid expression, and -\item -if the \grammarterm{qualified-id} \tcode{remove_reference_t::traits_type} -is valid and denotes a type, -\tcode{is_same_v::traits_type, traits>} is \tcode{true}. +is not a valid expression. \end{itemize} \pnum @@ -2010,7 +2006,7 @@ is designated by \tcode{charT}. \pnum -A specialization of \tcode{basic_string} is a contiguous container\iref{container.requirements.general}. +A specialization of \tcode{basic_string} is a contiguous container\iref{container.reqmts}. \pnum In all cases, @@ -2944,37 +2940,40 @@ \item \tcode{k} be \tcode{min(o, n)}. \item -\tcode{p} be a \tcode{charT*}, +\tcode{p} be a value of type \tcode{charT*} or \tcode{charT* const}, such that the range \crange{p}{p + n} is valid and \tcode{this->compare(0, k, p, k) == 0} is \tcode{true} before the call. The values in the range \crange{p + k}{p + n} may be indeterminate\iref{basic.indet}. \item -$OP$ be the expression \tcode{std::move(op)(p, n)}. +\tcode{m} be a value of type \tcode{size_type} or \tcode{const size_type} +equal to \tcode{n}. +\item +\tcode{\placeholder{OP}} be the expression \tcode{std::move(op)(p, m)}. \item -\tcode{r} = $OP$. +\tcode{r} = \tcode{\placeholder{OP}}. \end{itemize} \pnum \mandates -$OP$ has an integer-like type\iref{iterator.concept.winc}. +\tcode{\placeholder{OP}} has an integer-like type\iref{iterator.concept.winc}. \pnum \expects \begin{itemize} \item -$OP$ does not throw an exception or modify \tcode{p} or \tcode{n}. +\tcode{\placeholder{OP}} does not throw an exception or modify \tcode{p} or \tcode{m}. \item $\tcode{r} \geq 0$. \item -$\tcode{r} \leq \tcode{n}$. +$\tcode{r} \leq \tcode{m}$. \item -After evaluating $OP$ +After evaluating \tcode{\placeholder{OP}} there are no indeterminate values in the range \range{p}{p + r}. \end{itemize} \pnum \effects -Evaluates $OP$, +Evaluates \tcode{\placeholder{OP}}, replaces the contents of \tcode{*this} with \range{p}{p + r}, and invalidates all pointers and references to the range \crange{p}{p + n}. @@ -2982,7 +2981,7 @@ \recommended Implementations should avoid unnecessary copies and allocations by, for example, making \tcode{p} a pointer into internal storage and -by restoring \tcode{*(p + r)} to \tcode{charT()} after evaluating $OP$. +by restoring \tcode{*(p + r)} to \tcode{charT()} after evaluating \tcode{\placeholder{OP}}. \end{itemdescr} \indexlibrarymember{capacity}{basic_string}% diff --git a/source/styles.tex b/source/styles.tex index a5dd6c9ee9..d77f983b38 100644 --- a/source/styles.tex +++ b/source/styles.tex @@ -142,14 +142,6 @@ %% (copied verbatim from listings.sty version 1.6 except where commented) \makeatletter -\lst@CheckVersion{1.8d}{\lst@CheckVersion{1.8c}{\lst@CheckVersion{1.8b}{\lst@CheckVersion{1.7}{\lst@CheckVersion{1.6}{\lst@CheckVersion{1.5b}{ - \typeout{^^J% - ***^^J% - *** This file requires listings.sty version 1.6.^^J% - *** You have version \lst@version; exiting ...^^J% - ***^^J}% - \batchmode \@@end}}}}}} - \def\lst@Init#1{% \begingroup \ifx\lst@float\relax\else @@ -262,7 +254,7 @@ \ifvmode\else\par\fi\lst@emptylinepenalty \vskip\parskip \vskip\baselineskip - % \lsthk@EveryLine has \lst@parshape, i.e. \parshape, which causes an \hbox + % \lsthk@EveryLine has \lst@parshape, i.e., \parshape, which causes an \hbox % \lsthk@EveryPar increments line counters; \refstepcounter balloons the PDF \global\advance\lst@newlines\m@ne \lst@newlinetrue} diff --git a/source/support.tex b/source/support.tex index 62d366aca3..1d23489e88 100644 --- a/source/support.tex +++ b/source/support.tex @@ -550,7 +550,6 @@ \end{note} \begin{codeblock} -// all freestanding #define @\defnlibxname{cpp_lib_addressof_constexpr}@ 201603L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_algorithm_iterator_requirements}@ 202207L // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory} @@ -574,7 +573,7 @@ #define @\defnlibxname{cpp_lib_atomic_shared_ptr}@ 201711L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // also in \libheader{atomic}, \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // also in \libheader{atomic} -#define @\defnlibxname{cpp_lib_barrier}@ 201907L // also in \libheader{barrier} +#define @\defnlibxname{cpp_lib_barrier}@ 202302L // also in \libheader{barrier} #define @\defnlibxname{cpp_lib_bind_back}@ 202202L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_bind_front}@ 201907L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // also in \libheader{bit} @@ -589,10 +588,12 @@ #define @\defnlibxname{cpp_lib_chrono}@ 201907L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_chrono_udls}@ 201304L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_clamp}@ 201603L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_common_reference}@ 202302L // also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_common_reference_wrapper}@ 202302L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202207L // also in \libheader{concepts}, \libheader{compare} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm}, \libheader{utility} -#define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202202L // also in \libheader{bitset} +#define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202207L // also in \libheader{bitset} #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 201711L // also in \libheader{complex} @@ -621,11 +622,11 @@ #define @\defnlibxname{cpp_lib_execution}@ 201902L // also in \libheader{execution} #define @\defnlibxname{cpp_lib_expected}@ 202211L // also in \libheader{expected} #define @\defnlibxname{cpp_lib_filesystem}@ 201703L // also in \libheader{filesystem} -#define @\defnlibxname{cpp_lib_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} #define @\defnlibxname{cpp_lib_flat_set}@ 202207L // also in \libheader{flat_set} #define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_format_ranges}@ 202207L // also in \libheader{format} +#define @\defnlibxname{cpp_lib_formatters}@ 202302L // also in \libheader{stacktrace}, \libheader{thread} #define @\defnlibxname{cpp_lib_forward_like}@ 202207L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generator}@ 202207L // also in \libheader{generator} @@ -648,6 +649,7 @@ #define @\defnlibxname{cpp_lib_is_aggregate}@ 201703L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_constant_evaluated}@ 201811L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_final}@ 201402L // also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_implicit_lifetime}@ 202302L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_invocable}@ 201703L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_layout_compatible}@ 201907L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_nothrow_convertible}@ 201806L // also in \libheader{type_traits} @@ -684,7 +686,7 @@ #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} -#define @\defnlibxname{cpp_lib_ranges}@ 202211L +#define @\defnlibxname{cpp_lib_ranges}@ 202302L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges} @@ -692,6 +694,8 @@ #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_ranges_enumerate}@ 202302L // also in \libheader{ranges}, \libheader{version} +#define @\defnlibxname{cpp_lib_ranges_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_fold}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} @@ -755,14 +759,12 @@ \indextext{\idxcode{numeric_limits}}% \indexlibraryglobal{numeric_limits}% \indexlibraryglobal{float_round_style}% -\indexlibraryglobal{float_denorm_style}% \begin{codeblock} // all freestanding namespace std { - // \ref{fp.style}, floating-point type properties + // \ref{round.style}, enumeration \tcode{float_round_style} enum float_round_style; - enum float_denorm_style; // \ref{numeric.limits}, class template \tcode{numeric_limits} template class numeric_limits; @@ -796,9 +798,7 @@ } \end{codeblock} -\rSec2[fp.style]{Floating-point type properties} - -\rSec3[round.style]{Type \tcode{float_round_style}} +\rSec2[round.style]{Enum \tcode{float_round_style}} \indexlibraryglobal{float_round_style}% \begin{codeblock} @@ -839,41 +839,6 @@ if the rounding style is toward negative infinity \end{itemize} -\rSec3[denorm.style]{Type \tcode{float_denorm_style}} - -\indexlibraryglobal{float_denorm_style}% -\begin{codeblock} -namespace std { - enum float_denorm_style { - denorm_indeterminate = -1, - denorm_absent = 0, - denorm_present = 1 - }; -} -\end{codeblock} - -\indextext{denormalized value|see{number, subnormal}}% -\indextext{value!denormalized|see{number, subnormal}}% -\indextext{subnormal number|see{number, subnormal}}% -\indextext{number!subnormal}% -\pnum -The presence or absence of subnormal numbers (variable number of exponent bits) -is characterized by the values: -\begin{itemize} -\item -\indexlibraryglobal{denorm_indeterminate}% -\tcode{denorm_indeterminate} -if it cannot be determined whether or not the type allows subnormal values -\item -\indexlibraryglobal{denorm_absent}% -\tcode{denorm_absent} -if the type does not allow subnormal values -\item -\indexlibraryglobal{denorm_present}% -\tcode{denorm_present} -if the type does allow subnormal values -\end{itemize} - \rSec2[numeric.limits]{Class template \tcode{numeric_limits}} \rSec3[numeric.limits.general]{General} @@ -914,8 +879,6 @@ static constexpr bool has_infinity = false; static constexpr bool has_quiet_NaN = false; static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; static constexpr T infinity() noexcept { return T(); } static constexpr T quiet_NaN() noexcept { return T(); } static constexpr T signaling_NaN() noexcept { return T(); } @@ -1155,8 +1118,7 @@ For integer types, specifies the base of the representation. \begin{footnote} -Distinguishes types with bases other than 2 (e.g. -BCD). +Distinguishes types with bases other than 2 (e.g., BCD). \end{footnote} \pnum @@ -1336,46 +1298,6 @@ \tcode{is_iec559 != false}. \end{itemdescr} -\indexlibrarymember{float_denorm_style}{numeric_limits}% -\begin{itemdecl} -static constexpr float_denorm_style has_denorm; -\end{itemdecl} - -\indextext{number!subnormal}% -\begin{itemdescr} -\pnum -\tcode{denorm_present} -if the type allows subnormal values -(variable number of exponent bits), -\begin{footnote} -Required by LIA-1. -\end{footnote} -\tcode{denorm_absent} -if the type does not allow subnormal values, -and -\tcode{denorm_indeterminate} -if it is indeterminate at compile time whether the type allows -subnormal values. - -\pnum -Meaningful for all floating-point types. -\end{itemdescr} - -\indexlibrarymember{has_denorm_loss}{numeric_limits}% -\begin{itemdecl} -static constexpr bool has_denorm_loss; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{true} if loss of accuracy is detected as a -denormalization loss, rather than as an inexact result. -\begin{footnote} -See -ISO/IEC/IEEE 60559. -\end{footnote} -\end{itemdescr} - \indexlibrarymember{infinity}{numeric_limits}% \begin{itemdecl} static constexpr T infinity() noexcept; @@ -1441,18 +1363,14 @@ \begin{itemdescr} \indextext{number!subnormal}% \pnum -Minimum positive subnormal value. +Minimum positive subnormal value, if available. \begin{footnote} Required by LIA-1. \end{footnote} +Otherwise, minimum positive normalized value. \pnum Meaningful for all floating-point types. - -\pnum -In specializations for which -\tcode{has_denorm == false}, -returns the minimum positive normalized value. \end{itemdescr} \indexlibrarymember{is_iec559}{numeric_limits}% @@ -1626,8 +1544,6 @@ static constexpr bool has_infinity = true; static constexpr bool has_quiet_NaN = true; static constexpr bool has_signaling_NaN = true; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; static constexpr float infinity() noexcept { return @\textit{value}@; } static constexpr float quiet_NaN() noexcept { return @\textit{value}@; } @@ -1679,8 +1595,6 @@ static constexpr bool has_infinity = false; static constexpr bool has_quiet_NaN = false; static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; static constexpr bool infinity() noexcept { return 0; } static constexpr bool quiet_NaN() noexcept { return 0; } static constexpr bool signaling_NaN() noexcept { return 0; } @@ -5913,6 +5827,13 @@ \item \tcode{f} is the member function \tcode{is_lock_free()}, or +\item +\tcode{f} is a non-static member function of class \tcode{atomic_flag}, or + +\item +\tcode{f} is a non-member function, and +the first parameter of \tcode{f} has type \cv{}~\tcode{atomic_flag*}, or + \item \tcode{f} is a non-static member function invoked on an object \tcode{A}, such that \tcode{A.is_lock_free()} yields \tcode{true}, or @@ -6084,11 +6005,6 @@ \rSec2[stdalign.h.syn]{Header \tcode{} synopsis} \indexheader{stdalign.h}% -\indexlibraryglobal{__alignas_is_defined}% -\begin{codeblock} -#define @\xname{alignas_is_defined}@ 1 -\end{codeblock} - \pnum The contents of the \Cpp{} header \libheader{stdalign.h} are the same as the C standard library header \libheader{stdalign.h}, with the following changes: @@ -6101,11 +6017,6 @@ \indexheader{stdbool.h}% \indexhdr{stdbool.h}% -\indexlibraryglobal{__bool_true_false_are_defined}% -\begin{codeblock} -#define @\xname{bool_true_false_are_defined}@ 1 -\end{codeblock} - \pnum The contents of the \Cpp{} header \libheader{stdbool.h} are the same as the C standard library header \libheader{stdbool.h}, with the following changes: diff --git a/source/tables.tex b/source/tables.tex index b5c14fa689..c1f20586f0 100644 --- a/source/tables.tex +++ b/source/tables.tex @@ -63,7 +63,7 @@ % General Usage: TITLE is the title of the table, XREF is the % cross-reference for the table. LAYOUT is a sequence of column -% type specifiers (e.g. cp{1.0}c), without '|' for the left edge +% type specifiers (e.g., cp{1.0}c), without '|' for the left edge % or right edge. % usage: \begin{floattablebase}{TITLE}{XREF}{LAYOUT}{PLACEMENT} diff --git a/source/templates.tex b/source/templates.tex index c726e771ff..613c87eb19 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -172,6 +172,13 @@ templated entity is a templated entity. \end{note} +A \defnadj{templated}{function} is +a function template or a function that is templated. +A \defnadj{templated}{class} is +a class template or a class that is templated. +A \defnadj{templated}{variable} is +a variable template or a variable that is templated. + \pnum A \grammarterm{template-declaration} is written in terms of its template parameters. @@ -2840,7 +2847,7 @@ \begin{itemize} \item % Note: "\space" used below because " " inside tcode adds too much whitespace; -% one could optionally use mathfont inside tcode, e.g. "\tcode{($ $}". +% one could optionally use mathfont inside tcode, e.g., "\tcode{($ $}". \tcode{(}\space \tcode{((}$\mathtt{E}_1$ \placeholder{op} $\mathtt{E}_2$\tcode{)} @@ -4437,7 +4444,9 @@ The program is ill-formed, no diagnostic required, if: \begin{itemize} \item -no valid specialization can be generated for a template +no valid specialization, +ignoring \grammarterm{static_assert-declaration}{s} that fail, +can be generated for a template or a substatement of a constexpr if statement\iref{stmt.if} within a template and the template is not instantiated, or \item @@ -5991,7 +6000,7 @@ causes specializations in the default member initializer to be instantiated. \pnum -If a function template +If a templated function \tcode{f} is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, @@ -6436,7 +6445,7 @@ The definition of an explicitly specialized class is unrelated to the definition of a generated specialization. That is, its members need -not have the same names, types, etc. as the members of a generated +not have the same names, types, etc.\ as the members of a generated specialization. Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and @@ -6604,7 +6613,7 @@ \pnum Whether an explicit specialization of a function or variable template -is inline, constexpr, or an immediate function +is inline, constexpr, constinit, or consteval is determined by the explicit specialization and is independent of those properties of the template. Similarly, @@ -7702,7 +7711,7 @@ \tcode{A}, and the deduction is done as described in~\ref{temp.deduct.type}. -Otherwise, deduction is performed with empty sets of types P and A. +Otherwise, deduction is performed with empty sets of types \tcode{P} and \tcode{A}. \pnum A placeholder type\iref{dcl.spec.auto} in the return type of a diff --git a/source/threads.tex b/source/threads.tex index accde75f3e..e4fa6273c9 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -9,7 +9,7 @@ and values between threads, as summarized in \tref{thread.summary}. -\begin{libsumtab}{Thread support library summary}{thread.summary} +\begin{libsumtab}{Concurrency support library summary}{thread.summary} \ref{thread.req} & Requirements & \\ \rowsep \ref{thread.stoptoken}& Stop tokens & \tcode{} \\ \rowsep \ref{thread.threads} & Threads & \tcode{} \\ \rowsep @@ -1204,6 +1204,8 @@ basic_ostream& operator<<(basic_ostream& out, thread::id id); + template struct formatter; + // hash support template struct hash; template<> struct hash; @@ -1220,6 +1222,16 @@ equal to the \tcode{thread::id} object of any \tcode{thread} object that does not represent threads of execution. +\pnum +The \defn{text representation} for +the character type \tcode{charT} of an object of type \tcode{thread::id} +is an unspecified sequence of \tcode{charT} such that, +for two objects of type \tcode{thread::id} \tcode{x} and \tcode{y}, +if \tcode{x == y} is \tcode{true}, +the \tcode{thread::id} objects have the same text representation, and +if \tcode{x != y} is \tcode{true}, +the \tcode{thread::id} objects have distinct text representations. + \pnum \tcode{thread::id} is a trivially copyable class\iref{class.prop}. The library may reuse the value of a \tcode{thread::id} of a terminated thread that can no longer be joined. @@ -1283,17 +1295,44 @@ \begin{itemdescr} \pnum \effects -Inserts an unspecified text representation of \tcode{id} into -\tcode{out}. For two objects of type \tcode{thread::id} \tcode{x} and \tcode{y}, -if \tcode{x == y} the \tcode{thread::id} objects have the same text -representation and if \tcode{x != y} the \tcode{thread::id} objects have -distinct text representations. +Inserts the text representation for \tcode{charT} of \tcode{id} into +\tcode{out}. \pnum \returns \tcode{out}. \end{itemdescr} +\indexlibrary{\idxcode{formatter}!specializations!\idxcode{thread::id}}% +\begin{itemdecl} +template struct formatter; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{formatter} interprets \fmtgrammarterm{format-spec} +as a \fmtgrammarterm{thread-id-format-spec}. +The syntax of format specifications is as follows: + +\begin{ncbnf} +\fmtnontermdef{thread-id-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 +If the \fmtgrammarterm{align} option is omitted it defaults to \tcode{>}. + +\pnum +A \tcode{thread::id} object is formatted by +writing its text representation for \tcode{charT} to the output +with additional padding and adjustments as specified by the format specifiers. +\end{itemdescr} + \indexlibrarymember{hash}{thread::id}% \begin{itemdecl} template<> struct hash; @@ -4828,12 +4867,12 @@ atomic> head; public: - auto find(T t) const { + shared_ptr find(T t) const { auto p = head.load(); while (p && p->t != t) p = p->next; - return shared_ptr(move(p)); + return p; } void push_front(T t) { @@ -9604,15 +9643,11 @@ The expected count is decremented by each call to \tcode{arrive} or \tcode{arrive_and_drop}. \item - When the expected count reaches zero, the phase completion step is run. - For the specialization - with the default value of the \tcode{CompletionFunction} template parameter, - the completion step is run - as part of the call to \tcode{arrive} or \tcode{arrive_and_drop} - that caused the expected count to reach zero. - For other specializations, - the completion step is run on one of the threads - that arrived at the barrier during the phase. + Exactly once after the expected count reaches zero, a thread + executes the completion step during its call + to \tcode{arrive}, \tcode{arrive_and_drop}, or \tcode{wait}, + except that it is \impldef{barrier phrase completion without \tcode{wait}} + whether the step executes if no thread calls \tcode{wait}. \item When the completion step finishes, the expected count is reset diff --git a/source/time.tex b/source/time.tex index 04f414aba6..ccfce44fbf 100644 --- a/source/time.tex +++ b/source/time.tex @@ -597,7 +597,7 @@ template basic_ostream& - operator<<(basic_ostream& os, const year_month_weekday& ymwdi); + operator<<(basic_ostream& os, const year_month_weekday& ymwd); // \ref{time.cal.ymwdlast}, class \tcode{year_month_weekday_last} class year_month_weekday_last; @@ -10478,10 +10478,11 @@ are described in \ref{format.string}. Giving a \fmtgrammarterm{precision} specification in the \fmtgrammarterm{chrono-format-spec} -is valid only for \tcode{std::chrono::duration} types -where the representation type \tcode{Rep} -is a floating-point type. -For all other \tcode{Rep} types, +is valid only for types that are +specializations of \tcode{std::chrono::duration} +for which the nested \grammarterm{typedef-name} \tcode{rep} denotes +a floating-point type. +For all other types, an exception of type \tcode{format_error} is thrown if the \fmtgrammarterm{chrono-format-spec} contains a \fmtgrammarterm{precision} specification. @@ -10560,7 +10561,7 @@ to format as a \tcode{weekday}. \end{example} However, if a flag refers to a ``time of day'' -(e.g. \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.), +(e.g., \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.), then a specialization of \tcode{duration} is interpreted as the time of day elapsed since midnight. @@ -11174,7 +11175,7 @@ A \tcode{duration} cannot represent a \tcode{weekday}. \end{example} However, if a flag refers to a ``time of day'' -(e.g. \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.), +(e.g., \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.), then a specialization of \tcode{duration} is parsed as the time of day elapsed since midnight. @@ -11401,7 +11402,7 @@ \tcode{\%y} & The last two decimal digits of the year. If the century is not otherwise specified -(e.g. with \tcode{\%C}), +(e.g., with \tcode{\%C}), values in the range \crange{69}{99} are presumed to refer to the years 1969 to 1999, and values in the range \crange{00}{68} diff --git a/source/utilities.tex b/source/utilities.tex index 03f38b6e3f..6bd360c47f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -136,12 +136,12 @@ }; // \ref{pairs.spec}, pair specialized algorithms - template - constexpr bool operator==(const pair&, const pair&); - template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, - @\placeholder{synth-three-way-result}@> - operator<=>(const pair&, const pair&); + template + constexpr bool operator==(const pair&, const pair&); + template + constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, + @\placeholder{synth-three-way-result}@> + operator<=>(const pair&, const pair&); template constexpr void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); @@ -247,8 +247,6 @@ \pnum \remarks -This function -is a designated customization point\iref{namespace.std}. The exception specification is equivalent to: \begin{codeblock} @@ -899,8 +897,11 @@ \constraints \begin{itemize} \item +For the last overload, +\tcode{remove_cvref_t

} is not a specialization of \tcode{ranges::subrange}, +\item \tcode{is_constructible_v(\exposid{FWD}(p)))>} -is \tcode{true} and +is \tcode{true}, and \item \tcode{is_constructible_v(\exposid{FWD}(p)))>} is \tcode{true}. @@ -1264,8 +1265,8 @@ \indexlibrarymember{operator==}{pair}% \begin{itemdecl} -template - constexpr bool operator==(const pair& x, const pair& y); +template + constexpr bool operator==(const pair& x, const pair& y); \end{itemdecl} \begin{itemdescr} @@ -1281,10 +1282,10 @@ \indexlibrarymember{operator<=>}{pair}% \begin{itemdecl} -template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, - @\placeholder{synth-three-way-result}@> - operator<=>(const pair& x, const pair& y); +template + constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, + @\placeholder{synth-three-way-result}@> + operator<=>(const pair& x, const pair& y); \end{itemdecl} \begin{itemdescr} @@ -3470,9 +3471,13 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_constructible_v} is \tcode{true}, -\tcode{is_same_v, in_place_t>} is \tcode{false}, and -\tcode{is_same_v, optional>} is \tcode{false}. +\begin{itemize} +\item \tcode{is_constructible_v} is \tcode{true}, +\item \tcode{is_same_v, in_place_t>} is \tcode{false}, +\item \tcode{is_same_v, optional>} is \tcode{false}, and +\item if \tcode{T} is \cv{} \tcode{bool}, +\tcode{remove_cvref_t} is not a specialization of \tcode{optional}. +\end{itemize} \pnum \effects @@ -3506,7 +3511,8 @@ \constraints \begin{itemize} \item \tcode{is_constructible_v} is \tcode{true}, and -\item \tcode{\exposid{converts-from-any-cvref}>} is \tcode{false}. +\item if \tcode{T} is not \cv{} \tcode{bool}, +\tcode{\exposid{converts-from-any-cvref}>} is \tcode{false}. \end{itemize} \pnum @@ -3540,7 +3546,8 @@ \constraints \begin{itemize} \item \tcode{is_constructible_v} is \tcode{true}, and -\item \tcode{\exposid{converts-from-any-cvref}>} is \tcode{false}. +\item if \tcode{T} is not \cv{} \tcode{bool}, +\tcode{\exposid{converts-from-any-cvref}>} is \tcode{false}. \end{itemize} \pnum @@ -7506,6 +7513,7 @@ \item \tcode{is_constructible_v} is \tcode{true}; and \item +if \tcode{T} is not \cv{} \tcode{bool}, \tcode{\exposid{converts-from-any-cvref}>} is \tcode{false}; and \item \tcode{is_constructible_v, expected\&>} is \tcode{false}; and @@ -7556,7 +7564,10 @@ \item \tcode{remove_cvref_t} is not a specialization of \tcode{unexpected}; and \item -\tcode{is_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}; and +\item +if \tcode{T} is \cv{} \tcode{bool}, +\tcode{remove_cvref_t} is not a specialization of \tcode{expected}. \end{itemize} \pnum @@ -8156,13 +8167,17 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{is_copy_constructible_v} is \tcode{true}. + \pnum \returns \exposid{val}, if \tcode{has_value()} is \tcode{true}. \pnum \throws -\tcode{bad_expected_access(error())} if \tcode{has_value()} is \tcode{false}. +\tcode{bad_expected_access(as_const(error()))} if \tcode{has_value()} is \tcode{false}. \end{itemdescr} \indexlibrarymember{value}{expected}% @@ -8172,6 +8187,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{is_copy_constructible_v} is \tcode{true} and +\tcode{is_constructible_v} is \tcode{true}. + \pnum \returns \tcode{std::move(\exposid{val})}, if \tcode{has_value()} is \tcode{true}. @@ -8294,7 +8314,7 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8325,7 +8345,7 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8355,7 +8375,7 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8386,7 +8406,7 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8417,7 +8437,7 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8459,7 +8479,7 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -8499,11 +8519,12 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates -\tcode{G} is a valid value type for \tcode{expected} and the declaration +\tcode{G} is a valid template argument +for \tcode{unexpected}\iref{expected.un.general} and the declaration \begin{codeblock} G g(invoke(std::forward(f), error())); \end{codeblock} @@ -8530,11 +8551,12 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates -\tcode{G} is a valid value type for \tcode{expected} and the declaration +\tcode{G} is a valid template argument +for \tcode{unexpected}\iref{expected.un.general} and the declaration \begin{codeblock} G g(invoke(std::forward(f), std::move(error()))); \end{codeblock} @@ -8581,7 +8603,7 @@ The expression \tcode{*x == v} is well-formed and its result is convertible to \tcode{bool}. \begin{note} -\tcode{T1} need not be \oldconcept{EqualityComparable}. +\tcode{T} need not be \oldconcept{EqualityComparable}. \end{note} \pnum @@ -9263,7 +9285,7 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v>} is \tcode{true}. \pnum \mandates @@ -9293,7 +9315,7 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -9376,7 +9398,7 @@ \pnum \constraints -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -9416,7 +9438,7 @@ \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true}. +\tcode{is_constructible_v} is \tcode{true}. \pnum \mandates @@ -9456,7 +9478,8 @@ \pnum \mandates -\tcode{G} is a valid value type for \tcode{expected} and the declaration +\tcode{G} is a valid template argument +for \tcode{unexpected}\iref{expected.un.general} and the declaration \begin{codeblock} G g(invoke(std::forward(f), error())); \end{codeblock} @@ -9483,7 +9506,8 @@ \pnum \mandates -\tcode{G} is a valid value type for \tcode{expected} and the declaration +\tcode{G} is a valid template argument +for \tcode{unexpected}\iref{expected.un.general} and the declaration \begin{codeblock} G g(invoke(std::forward(f), std::move(error()))); \end{codeblock} @@ -10429,6 +10453,15 @@ template constexpr reference_wrapper cref(reference_wrapper) noexcept; // freestanding + // \ref{refwrap.common.ref}, \tcode{common_reference} related specializations + template class RQual, template class TQual> + requires @\seebelow@ + struct basic_common_reference; + + template class TQual, template class RQual> + requires @\seebelow@ + struct basic_common_reference; + // \ref{arithmetic.operations}, arithmetic operations template struct plus; // freestanding template struct minus; // freestanding @@ -10634,7 +10667,9 @@ \begin{itemize} \item \tcode{(t$_1$.*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} -and \tcode{is_base_of_v>} is \tcode{true}; +and +\tcode{is_same_v> ||} +\tcode{is_base_of_v>} is \tcode{true}; \item \tcode{(t$_1$.get().*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} @@ -10644,15 +10679,17 @@ member function of a class \tcode{T} and \tcode{t$_1$} does not satisfy the previous two items; -\item \tcode{t$_1$.*f} when \tcode{N == 1} and \tcode{f} is a pointer to +\item \tcode{t$_1$.*f} when $N = 1$ and \tcode{f} is a pointer to data member of a class \tcode{T} -and \tcode{is_base_of_v>} is \tcode{true}; +and +\tcode{is_same_v> ||} +\tcode{is_base_of_v>} is \tcode{true}; -\item \tcode{t$_1$.get().*f} when \tcode{N == 1} and \tcode{f} is a pointer to +\item \tcode{t$_1$.get().*f} when $N = 1$ and \tcode{f} is a pointer to data member of a class \tcode{T} and \tcode{remove_cvref_t} is a specialization of \tcode{reference_wrapper}; -\item \tcode{(*t$_1$).*f} when \tcode{N == 1} and \tcode{f} is a pointer to +\item \tcode{(*t$_1$).*f} when $N = 1$ and \tcode{f} is a pointer to data member of a class \tcode{T} and \tcode{t$_1$} does not satisfy the previous two items; @@ -10976,6 +11013,39 @@ \tcode{t}. \end{itemdescr} +\rSec3[refwrap.common.ref]{\tcode{common_reference} related specializations} + +\indexlibraryglobal{basic_common_reference}% +\begin{codeblock} +namespace std { + template + constexpr bool @\exposid{is-ref-wrapper}@ = false; // \expos + + template + constexpr bool @\exposid{is-ref-wrapper}@> = true; + + template + concept @\defexposconcept{ref-wrap-common-reference-exists-with}@ = // \expos + @\exposid{is-ref-wrapper}@ && + requires { typename common_reference_t; } && + @\libconcept{convertible_to}@>; + + template class RQual, template class TQual> + requires (@\exposconcept{ref-wrap-common-reference-exists-with}@, TQual> && + !@\exposconcept{ref-wrap-common-reference-exists-with}@, RQual>) + struct basic_common_reference { + using type = common_reference_t>; + }; + + template class TQual, template class RQual> + requires (@\exposconcept{ref-wrap-common-reference-exists-with}@, TQual> && + !@\exposconcept{ref-wrap-common-reference-exists-with}@, RQual>) + struct basic_common_reference { + using type = common_reference_t>; + }; +} +\end{codeblock} + \rSec2[arithmetic.operations]{Arithmetic operations} \rSec3[arithmetic.operations.general]{General} @@ -12073,7 +12143,7 @@ \indexlibrarymember{operator()}{bit_not<>}% \begin{itemdecl} -template constexpr auto operator()(T&&) const +template constexpr auto operator()(T&& t) const -> decltype(~std::forward(t)); \end{itemdecl} @@ -14602,12 +14672,6 @@ \rSec3[format.string.general]{In general} -% FIXME: For now, keep the format grammar productions out of the index, since -% they conflict with the main grammar. -% Consider renaming these en masse (to fmt-* ?) to avoid this problem. -\newcommand{\fmtnontermdef}[1]{{\BnfNontermshape#1\itcorr}\textnormal{:}} -\newcommand{\fmtgrammarterm}[1]{\gterm{#1}} - \pnum A \defn{format string} for arguments \tcode{args} is a (possibly empty) sequence of @@ -14739,14 +14803,14 @@ \rSec3[format.string.std]{Standard format specifiers} \pnum -Each \tcode{formatter} specializations +Each \tcode{formatter} specialization described in \ref{format.formatter.spec} for fundamental and string types interprets \fmtgrammarterm{format-spec} as a \fmtgrammarterm{std-format-spec}. \begin{note} The format specification can be used to specify such details as -field width, alignment, padding, and decimal precision. +minimum field width, alignment, padding, and decimal precision. Some of the formatting options are only supported for arithmetic types. \end{note} @@ -14795,49 +14859,94 @@ \end{ncbnf} \pnum +Field widths are specified in defnadj{field width}{units}; +the number of column positions required to display a sequence of +characters in a terminal. +The \defnadj{minimum}{field width} +is the number of field width units a replacement field minimally requires of +the formatted sequence of characters produced for a format argument. +The \defnadj{estimated}{field width} is the number of field width units +that are required for the formatted sequence of characters +produced for a format argument independent of +the effects of the \fmtgrammarterm{width} option. +The \defnadj{padding}{width} is the greater of \tcode{0} and +the difference of the minimum field width and the estimated field width. + +\begin{note} +The POSIX \tcode{wcswidth} function is an example of a function that, +given a string, returns the number of column positions required by +a terminal to display the string. +\end{note} + +\pnum +The \defnadj{fill}{character} is the character denoted by +the \fmtgrammarterm{fill} option or, +if the \fmtgrammarterm{fill} option is absent, the space character. +For a format specification in UTF-8, UTF-16, or UTF-32, +the fill character corresponds to a single Unicode scalar value. \begin{note} -The \fmtgrammarterm{fill} character can be any character -other than \tcode{\{} or \tcode{\}}. -The presence of a fill character is signaled by the -character following it, which must be one of the alignment options. +The presence of a \fmtgrammarterm{fill} option +is signaled by the character following it, +which must be one of the alignment options. If the second character of \fmtgrammarterm{std-format-spec} is not a valid alignment option, -then it is assumed that both the fill character and the alignment option are -absent. +then it is assumed that +the \fmtgrammarterm{fill} and \fmtgrammarterm{align} options +are both absent. \end{note} \pnum -The \fmtgrammarterm{align} specifier applies to all argument types. +The \fmtgrammarterm{align} option applies to all argument types. The meaning of the various alignment options is as specified in \tref{format.align}. \begin{example} +%FIXME: example is incomplete, sB and sC result in: +%Error: Invalid UTF-8 byte sequence. \begin{codeblock} char c = 120; -string s0 = format("{:6}", 42); // value of \tcode{s0} is \tcode{"\ \ \ \ 42"} -string s1 = format("{:6}", 'x'); // value of \tcode{s1} is \tcode{"x\ \ \ \ \ "} -string s2 = format("{:*<6}", 'x'); // value of \tcode{s2} is \tcode{"x*****"} -string s3 = format("{:*>6}", 'x'); // value of \tcode{s3} is \tcode{"*****x"} -string s4 = format("{:*^6}", 'x'); // value of \tcode{s4} is \tcode{"**x***"} -string s5 = format("{:6d}", c); // value of \tcode{s5} is \tcode{"\ \ \ 120"} -string s6 = format("{:6}", true); // value of \tcode{s6} is \tcode{"true\ \ "} +string s0 = format("{:6}", 42); // value of \tcode{s0} is \tcode{"\ \ \ \ 42"} +string s1 = format("{:6}", 'x'); // value of \tcode{s1} is \tcode{"x\ \ \ \ \ "} +string s2 = format("{:*<6}", 'x'); // value of \tcode{s2} is \tcode{"x*****"} +string s3 = format("{:*>6}", 'x'); // value of \tcode{s3} is \tcode{"*****x"} +string s4 = format("{:*^6}", 'x'); // value of \tcode{s4} is \tcode{"**x***"} +string s5 = format("{:6d}", c); // value of \tcode{s5} is \tcode{"\ \ \ 120"} +string s6 = format("{:6}", true); // value of \tcode{s6} is \tcode{"true\ \ "} +string s7 = format("{:*<6.3}", "123456"); // value of \tcode{s7} is \tcode{"123***"} +string s8 = format("{:02}", 1234); // value of \tcode{s8} is \tcode{"1234"} +string s9 = format("{:*<}", "12"); // value of \tcode{s9} is \tcode{"12"} +string sA = format("{:*<6}", "12345678"); // value of \tcode{sA} is \tcode{"12345678"} \end{codeblock} \end{example} \begin{note} -Unless a minimum field width is defined, the field width is determined by -the size of the content and the alignment option has no effect. +The \fmtgrammarterm{fill}, \fmtgrammarterm{align}, and \tcode{0} options +have no effect when the minimum field width +is not greater than the estimated field width +because padding width is \tcode{0} in that case. +Since fill characters are assumed to have a field width of \tcode{1}, +use of a character with a different field width can produce misaligned output. +%FIXME: cannot show clown face character below. +The \unicode{1f921}{clown face} character has a field width of \tcode{2}. +The examples above that include that character +illustrate the effect of the field width +when that character is used as a fill character +as opposed to when it is used as a formatting argument. \end{note} \begin{floattable}{Meaning of \fmtgrammarterm{align} options}{format.align}{lp{.8\hsize}} \topline \lhdr{Option} & \rhdr{Meaning} \\ \rowsep \tcode{<} & -Forces the field to be aligned to the start of the available space. +Forces the formatted argument to be aligned to the start of the field +by inserting $n$ fill characters after the formatted argument +where $n$ is the padding width. This is the default for non-arithmetic non-pointer types, \tcode{charT}, and \tcode{bool}, unless an integer presentation type is specified. \\ \rowsep % \tcode{>} & -Forces the field to be aligned to the end of the available space. +Forces the formatted argument to be aligned to the end of the field +by inserting $n$ fill characters before the formatted argument +where $n$ is the padding width. This is the default for arithmetic types other than \tcode{charT} and \tcode{bool}, pointer types, @@ -14845,13 +14954,13 @@ \\ \rowsep % \tcode{\caret} & -Forces the field to be centered within the available space +Forces the formatted argument to be centered within the field by inserting $\bigl\lfloor \frac{n}{2} \bigr\rfloor$ -characters before and +fill characters before and $\bigl\lceil \frac{n}{2} \bigr\rceil$ -characters after the value, where -$n$ is the total number of fill characters to insert. +fill characters after the formatted argument, where +$n$ is the padding width. \\ \end{floattable} @@ -14927,56 +15036,52 @@ trailing zeros are not removed from the result. \pnum -A zero (\tcode{0}) character -preceding the \fmtgrammarterm{width} field -pads the field with leading zeros (following any indication of sign or base) -to the field width, -except when applied to an infinity or NaN. -This option is only valid for -arithmetic types other than \tcode{charT} and \tcode{bool} -or when an integer presentation type is specified. -If the \tcode{0} character and an \fmtgrammarterm{align} option both appear, -the \tcode{0} character is ignored. +The \tcode{0} option is valid for arithmetic types +other than \tcode{charT} and \tcode{bool} or +when an integer presentation type is specified. +For formatting arguments that have a value +other than an infinity or a NaN, +this option pads the formatted argument by +inserting the \tcode{0} character $n$ times +following the sign or base prefix indicators (if any) +where $n$ is \tcode{0} if the \fmtgrammarterm{align} option is present and +is the padding width otherwise. \begin{example} \begin{codeblock} char c = 120; string s1 = format("{:+06d}", c); // value of \tcode{s1} is \tcode{"+00120"} string s2 = format("{:#06x}", 0xa); // value of \tcode{s2} is \tcode{"0x000a"} -string s3 = format("{:<06}", -42); // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} is ignored because of \tcode{<} alignment) +string s3 = format("{:<06}", -42); // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} has no effect) +string s4 = format("{:06}", inf); // value of \tcode{s4} is \tcode{" inf"} (\tcode{0} has no effect) \end{codeblock} \end{example} +\pnum +The \fmtgrammarterm{width} option specifies the minimum field width. +If the \fmtgrammarterm{width} option is absent, +the minimum field width is \tcode{0}. + \pnum If \tcode{\{ \opt{\fmtgrammarterm{arg-id}} \}} is used in -a \fmtgrammarterm{width} or \fmtgrammarterm{precision}, -the value of the corresponding formatting argument is used in its place. -If the corresponding formatting argument is not of integral type, or +a \fmtgrammarterm{width} or \fmtgrammarterm{precision} option, +the value of the corresponding formatting argument is used as the value of the option. +If the corresponding formatting argument is +not of standard signed or unsigned integer type, or its value is negative, an exception of type \tcode{format_error} is thrown. \pnum % FIXME: What if it's an arg-id? -The \fmtgrammarterm{positive-integer} in -\fmtgrammarterm{width} is a decimal integer defining the minimum field width. -If \fmtgrammarterm{width} is not specified, -there is no minimum field width, and -the field width is determined based on the content of the field. - -\pnum -\indextext{string!width}% -The \defn{width} of a string is defined as -the estimated number of column positions appropriate -for displaying it in a terminal. -\begin{note} -This is similar to the semantics of the POSIX \tcode{wcswidth} function. -\end{note} +If \fmtgrammarterm{positive-integer} is used in a +\fmtgrammarterm{width} option, the value of the decimal integer +is used as the value of the option. \pnum For the purposes of width computation, a string is assumed to be in a locale-independent, \impldef{encoding assumption for \tcode{format} width computation} encoding. -Implementations should use a Unicode encoding +Implementations should use either UTF-8, UTF-16, or UTF-32, on platforms capable of displaying Unicode text in a terminal. \begin{note} This is the case for Windows @@ -14990,47 +15095,45 @@ \end{note} \pnum -For a string in a Unicode encoding, -implementations should estimate the width of a string -as the sum of estimated widths of -the first code points in its extended grapheme clusters. -The extended grapheme clusters of a string are defined by \UAX{29}. -The estimated width of the following code points is 2: +For a sequence of characters in UTF-8, UTF-16, or UTF-32, +an implementation should use as its field width +the sum of the field widths of the first code point +of each extended grapheme cluster. +Extended grapheme clusters are defined by \UAX{29} of the Unicode Standard. +The following code points have a field width of 2: \begin{itemize} -\item \ucode{1100} -- \ucode{115f} -\item \ucode{2329} -- \ucode{232a} -\item \ucode{2e80} -- \ucode{303e} -\item \ucode{3040} -- \ucode{a4cf} -\item \ucode{ac00} -- \ucode{d7a3} -\item \ucode{f900} -- \ucode{faff} -\item \ucode{fe10} -- \ucode{fe19} -\item \ucode{fe30} -- \ucode{fe6f} -\item \ucode{ff00} -- \ucode{ff60} -\item \ucode{ffe0} -- \ucode{ffe6} -\item \ucode{1f300} -- \ucode{1f64f} -\item \ucode{1f900} -- \ucode{1f9ff} -\item \ucode{20000} -- \ucode{2fffd} -\item \ucode{30000} -- \ucode{3fffd} +\item +any code point with the \tcode{East_Asian_Width="W"} or +\tcode{East_Asian_Width="F"} Derived Extracted Property as described by +\UAX{44} of the Unicode Standard +\item +\ucode{4dc0} -- \ucode{4dff} (Yijing Hexagram Symbols) +\item +\ucode{1f300} -- \ucode{1f5ff} (Miscellaneous Symbols and Pictographs) +\item +\ucode{1f900} -- \ucode{1f9ff} (Supplemental Symbols and Pictographs) \end{itemize} -The estimated width of other code points is 1. +The field width of all other code points is 1. \pnum -For a string in a non-Unicode encoding, the width of a string is unspecified. +For a sequence of characters in neither UTF-8, UTF-16, nor UTF-32, +the field width is unspecified. \pnum -% FIXME: What if it's an arg-id? -The \fmtgrammarterm{nonnegative-integer} in -\fmtgrammarterm{precision} is a decimal integer defining -the precision or maximum field size. -It can only be used with floating-point and string types. -For floating-point types this field specifies the formatting precision. -For string types, this field provides an upper bound -for the estimated width of the prefix of -the input string that is copied into the output. -For a string in a Unicode encoding, -the formatter copies to the output -the longest prefix of whole extended grapheme clusters -whose estimated width is no greater than the precision. +The \fmtgrammarterm{precision} option is valid +for floating-point and string types. +For floating-point types, +the value of this option specifies the precision +to be used for the floating-point presentation type. +For string types, +this option specifies the longest prefix of the formatted argument +to be included in the replacement field such that +the field width of the prefix is no greater than the value of this option. + +\pnum +If \fmtgrammarterm{nonnegative-integer} is used in +a \fmtgrammarterm{precision} option, +the value of the decimal integer is used as the value of the option. \pnum When the \tcode{L} option is used, the form used for the conversion is called @@ -15735,17 +15838,20 @@ \tcode{\libconcept{output_iterator}}\iref{iterator.concept.output}. \begin{codeblock} +template>> + concept @\defexposconcept{formattable-with}@ = // \expos + @\libconcept{semiregular}@ && + requires(Formatter& f, const Formatter& cf, T&& t, Context fc, + basic_format_parse_context pc) + { + { f.parse(pc) } -> @\libconcept{same_as}@; + { cf.format(t, fc) } -> @\libconcept{same_as}@; + }; + template concept @\deflibconcept{formattable}@ = - @\libconcept{semiregular}@, charT>> && - requires(formatter, charT> f, - const formatter, charT> cf, - T t, - basic_format_context<@\placeholder{fmt-iter-for}@, charT> fc, - basic_format_parse_context pc) { - { f.parse(pc) } -> @\libconcept{same_as}@::iterator>; - { cf.format(t, fc) } -> @\libconcept{same_as}@<@\placeholder{fmt-iter-for}@>; - }; + @\exposconcept{formattable-with}@, basic_format_context<@\placeholder{fmt-iter-for}@>>; \end{codeblock} \pnum @@ -15796,7 +15902,6 @@ template<> struct formatter; template<> struct formatter; template struct formatter; -template struct formatter; template struct formatter, charT>; template @@ -15930,15 +16035,23 @@ \begin{itemize} \item -\placeholder{CE} is a Unicode encoding and -\placeholder{C} corresponds to either -a UCS scalar value whose Unicode property \tcode{General_Category} -has a value in the groups \tcode{Separator} (\tcode{Z}) or \tcode{Other} (\tcode{C}) or to -a UCS scalar value which has the Unicode property \tcode{Grapheme_Extend=Yes}, -as described by table 12 of \UAX{44}, or +\placeholder{CE} is UTF-8, UTF-16, or UTF-32 and +\placeholder{C} corresponds to a Unicode scalar value +whose Unicode property \tcode{General_Category} has a value in the groups +\tcode{Separator} (\tcode{Z}) or \tcode{Other} (\tcode{C}), +as described by \UAX{44} of the Unicode Standard, or + +\item +\placeholder{CE} is UTF-8, UTF-16, or UTF-32 and +\placeholder{C} corresponds to a Unicode scalar value +with the Unicode property \tcode{Grapheme_Extend=Yes} +as described by \UAX{44} of the Unicode Standard and +\placeholder{C} is not immediately preceded in \placeholder{S} by +a character \placeholder{P} appended to \placeholder{E} +without translation to an escape sequence, or \item -\placeholder{CE} is not a Unicode encoding and +\placeholder{CE} is neither UTF-8, UTF-16, nor UTF-32 and \placeholder{C} is one of an implementation-defined set of separator or non-printable characters \end{itemize} @@ -16018,7 +16131,8 @@ then \placeholder{C} is appended unchanged. \end{itemize} -%% FIXME: Example is incomplete; s2 and s6 are missing below; +%% FIXME: Example is incomplete; s2 and s6 from P2286R8 +%% and s8 (which should be s9) from P2713R1 are missing below; %% FIXME: their Unicode characters are not available in our font (Latin Modern). \begin{example} \begin{codeblock} @@ -16030,6 +16144,8 @@ string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9)); // \tcode{s4} has value: \tcode{["\textbackslash u\{0\} \textbackslash n \textbackslash t \textbackslash u\{2\} \textbackslash u\{1b\}"]} string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8, \tcode{s5} has value: \tcode{["\textbackslash x\{c3\}("]} +string s7 = format("[{:?}]", "\u0301"); // \tcode{s7} has value: \tcode{["\textbackslash u{301}"]} +string s8 = format("[{:?}]", "\\\u0301"); // \tcode{s8} has value: \tcode{["\textbackslash \textbackslash \textbackslash u{301}"]} \end{codeblock} \end{example} @@ -16140,7 +16256,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{indexing_ != manual}, equivalent to: +If \tcode{indexing_ != manual} is \tcode{true}, equivalent to: \begin{codeblock} if (indexing_ == unknown) indexing_ = automatic; @@ -16149,8 +16265,14 @@ \pnum \throws -\tcode{format_error} if \tcode{indexing_ == manual} +\tcode{format_error} if \tcode{indexing_ == manual} is \tcode{true} which indicates mixing of automatic and manual argument indexing. + +\pnum +\remarks +Let \tcode{\placeholder{cur-arg-id}} be the value of \tcode{next_arg_id_} prior to this call. +Call expressions where \tcode{\placeholder{cur-arg-id} >= num_args_} is \tcode{true} +are not core constant expressions\iref{expr.const}. \end{itemdescr} \indexlibrarymember{check_arg_id}{basic_format_parse_context}% @@ -16161,7 +16283,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{indexing_ != automatic}, equivalent to: +If \tcode{indexing_ != automatic} is \tcode{true}, equivalent to: \begin{codeblock} if (indexing_ == unknown) indexing_ = manual; @@ -16170,12 +16292,12 @@ \pnum \throws \tcode{format_error} if -\tcode{indexing_ == automatic} which indicates mixing of automatic and -manual argument indexing. +\tcode{indexing_ == automatic} is \tcode{true} +which indicates mixing of automatic and manual argument indexing. \pnum \remarks -Call expressions where \tcode{id >= num_args_} are not +Call expressions where \tcode{id >= num_args_} is \tcode{true} are not core constant expressions\iref{expr.const}. \end{itemdescr} @@ -16398,11 +16520,11 @@ basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("]"); // \expos public: - constexpr void set_separator(basic_string_view sep); + constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, - basic_string_view closing); - constexpr formatter& underlying() { return @\exposid{underlying_}@; } - constexpr const formatter& underlying() const { return @\exposid{underlying_}@; } + basic_string_view closing) noexcept; + constexpr formatter& underlying() noexcept { return @\exposid{underlying_}@; } + constexpr const formatter& underlying() const noexcept { return @\exposid{underlying_}@; } template constexpr typename ParseContext::iterator @@ -16517,7 +16639,7 @@ \indexlibrarymember{set_separator}{range_formatter}% \begin{itemdecl} -constexpr void set_separator(basic_string_view sep); +constexpr void set_separator(basic_string_view sep) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16528,7 +16650,8 @@ \indexlibrarymember{set_brackets}{range_formatter}% \begin{itemdecl} -constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +constexpr void set_brackets(basic_string_view opening, + basic_string_view closing) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16632,9 +16755,9 @@ charT> @\exposid{underlying_}@; // \expos public: - constexpr void set_separator(basic_string_view sep); + constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, - basic_string_view closing); + basic_string_view closing) noexcept; template constexpr typename ParseContext::iterator @@ -16649,7 +16772,7 @@ \indexlibrarymemberexpos{set_separator}{range-default-formatter}% \begin{itemdecl} -constexpr void set_separator(basic_string_view sep); +constexpr void set_separator(basic_string_view sep) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16660,7 +16783,8 @@ \indexlibrarymemberexpos{set_brackets}{range-default-formatter}% \begin{itemdecl} -constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +constexpr void set_brackets(basic_string_view opening, + basic_string_view closing) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16736,7 +16860,7 @@ \exposid{element-type} is a specialization of \tcode{pair}, or \item \exposid{element-type} is a specialization of \tcode{tuple} and -\tcode{tuple_size_v == 2}. +\tcode{tuple_size_v<\exposid{element-type}> == 2}. \end{itemize} \pnum @@ -16930,24 +17054,7 @@ const char_type*, basic_string_view, const void*, handle> value; // \expos - template explicit basic_format_arg(T&& v) noexcept; // \expos - explicit basic_format_arg(float n) noexcept; // \expos - explicit basic_format_arg(double n) noexcept; // \expos - explicit basic_format_arg(long double n) noexcept; // \expos - explicit basic_format_arg(const char_type* s); // \expos - - template - explicit basic_format_arg( - basic_string_view s) noexcept; // \expos - - template - explicit basic_format_arg( - const basic_string& s) noexcept; // \expos - - explicit basic_format_arg(nullptr_t) noexcept; // \expos - - template - explicit basic_format_arg(T* p) noexcept; // \expos + template explicit basic_format_arg(T& v) noexcept; // \expos public: basic_format_arg() noexcept; @@ -16977,142 +17084,74 @@ \end{itemdescr} \begin{itemdecl} -template explicit basic_format_arg(T&& v) noexcept; +template explicit basic_format_arg(T& v) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints -The template specialization -\begin{codeblock} -typename Context::template formatter_type> -\end{codeblock} -meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements}. -The extent to which an implementation determines that -the specialization meets the \newoldconcept{BasicFormatter} requirements -is unspecified, -except that as a minimum the expression -\begin{codeblock} -typename Context::template formatter_type>() - .format(declval(), declval()) -\end{codeblock} -shall be well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}. +\tcode{T} satisfies \tcode{\exposconcept{formattable-with}}. + +\pnum +\expects +If \tcode{decay_t} is \tcode{char_type*} or \tcode{const char_type*}, +\tcode{static_cast(v)} points to a NTCTS\iref{defns.ntcts}. \pnum \effects +Let \tcode{TD} be \tcode{remove_const_t}. \begin{itemize} \item -if \tcode{T} is \tcode{bool} or \tcode{char_type}, +If \tcode{TD} is \tcode{bool} or \tcode{char_type}, initializes \tcode{value} with \tcode{v}; \item -otherwise, if \tcode{T} is \tcode{char} and \tcode{char_type} is +otherwise, if \tcode{TD} is \tcode{char} and \tcode{char_type} is \keyword{wchar_t}, initializes \tcode{value} with \tcode{static_cast(v)}; \item -otherwise, if \tcode{T} is a signed integer type\iref{basic.fundamental} -and \tcode{sizeof(T) <= sizeof(int)}, +otherwise, if \tcode{TD} is a signed integer type\iref{basic.fundamental} +and \tcode{sizeof(TD) <= sizeof(int)}, initializes \tcode{value} with \tcode{static_cast(v)}; \item -otherwise, if \tcode{T} is an unsigned integer type and -\tcode{sizeof(T) <= sizeof(unsigned int)}, initializes +otherwise, if \tcode{TD} is an unsigned integer type and +\tcode{sizeof(TD) <= sizeof(unsigned int)}, initializes \tcode{value} with \tcode{static_cast(v)}; \item -otherwise, if \tcode{T} is a signed integer type and -\tcode{sizeof(T) <= sizeof(long long int)}, initializes +otherwise, if \tcode{TD} is a signed integer type and +\tcode{sizeof(TD) <= sizeof(long long int)}, initializes \tcode{value} with \tcode{static_cast(v)}; \item -otherwise, if \tcode{T} is an unsigned integer type and -\tcode{sizeof(T) <= sizeof(unsigned long long int)}, initializes +otherwise, if \tcode{TD} is an unsigned integer type and +\tcode{sizeof(TD) <= sizeof(unsigned long long int)}, initializes \tcode{value} with \tcode{static_cast(v)}; \item +otherwise, if \tcode{TD} is a standard floating-point type, +initializes \tcode{value} with \tcode{v}; +\item +otherwise, if \tcode{TD} is +a specialization of \tcode{basic_string_view} or \tcode{basic_string} and +\tcode{TD::value_type} is \tcode{char_type}, +initializes \tcode{value} with +\tcode{basic_string_view(v.data(), v.size())}; +\item +otherwise, if \tcode{decay_t} is +\tcode{char_type*} or \tcode{const char_type*}, +initializes \tcode{value} with \tcode{static_cast(v)}; +\item +otherwise, if \tcode{is_void_v>} is \tcode{true} or +\tcode{is_null_pointer_v} is \tcode{true}, +initializes \tcode{value} with \tcode{static_cast(v)}; +\item otherwise, initializes \tcode{value} with \tcode{handle(v)}. \end{itemize} -\end{itemdescr} - -\begin{itemdecl} -explicit basic_format_arg(float n) noexcept; -explicit basic_format_arg(double n) noexcept; -explicit basic_format_arg(long double n) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \tcode{value} with \tcode{n}. -\end{itemdescr} - -\begin{itemdecl} -explicit basic_format_arg(const char_type* s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{s} points to a NTCTS\iref{defns.ntcts}. - -\pnum -\effects -Initializes \tcode{value} with \tcode{s}. -\end{itemdescr} - -\begin{itemdecl} -template - explicit basic_format_arg(basic_string_view s) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \tcode{value} with -\tcode{basic_string_view(s.data(), s.size())}. -\end{itemdescr} - -\begin{itemdecl} -template - explicit basic_format_arg( - const basic_string& s) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \tcode{value} with -\tcode{basic_string_view(s.data(), s.size())}. -\end{itemdescr} - -\begin{itemdecl} -explicit basic_format_arg(nullptr_t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \tcode{value} with - \tcode{static_cast(nullptr)}. -\end{itemdescr} - -\begin{itemdecl} -template explicit basic_format_arg(T* p) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{is_void_v} is \tcode{true}. - -\pnum -\effects -Initializes \tcode{value} with \tcode{p}. - -\pnum \begin{note} -Constructing \tcode{basic_format_arg} from -a pointer to a member is ill-formed unless -the user provides an enabled specialization of -\tcode{formatter} for that pointer to member type. +Constructing \tcode{basic_format_arg} from a pointer to a member is ill-formed +unless the user provides an enabled specialization of \tcode{formatter} +for that pointer to member type. \end{note} \end{itemdescr} + \indexlibrary{\idxcode{basic_format_arg}!constructor|)}% \indexlibrarymember{operator bool}{basic_format_arg}% @@ -17139,7 +17178,7 @@ void (*format_)(basic_format_parse_context&, Context&, const void*); // \expos - template explicit handle(T&& val) noexcept; // \expos + template explicit handle(T& val) noexcept; // \expos friend class basic_format_arg; // \expos @@ -17151,7 +17190,7 @@ \indexlibraryctor{basic_format_arg::handle}% \begin{itemdecl} -template explicit handle(T&& val) noexcept; +template explicit handle(T& val) noexcept; \end{itemdecl} \begin{itemdescr} @@ -17159,19 +17198,16 @@ Let \begin{itemize} \item -\tcode{TD} be \tcode{remove_cvref_t}, -\item -\exposid{const-formattable} be \tcode{true} if -\tcode{typename Context::template formatter_type()\newline .format(declval(), declval())} is well-formed, otherwise \tcode{false}, +\tcode{TD} be \tcode{remove_const_t}, \item -\tcode{TQ} be \tcode{const TD} if \exposid{const-formattable} is \tcode{true} +\tcode{TQ} be \tcode{const TD} if +\tcode{const TD} satisfies \tcode{\exposconcept{formattable-with}} and \tcode{TD} otherwise. \end{itemize} \pnum \mandates -\tcode{\exposid{const-formattable} || !is_const_v>} is -\tcode{true}. +\tcode{TQ} satisfies \tcode{\exposconcept{formattable-with}}. \pnum \effects @@ -17236,7 +17272,7 @@ \pnum \expects The type -\tcode{typename Context::template formatter_type<}$\tcode{T}_i$\tcode{>} +\tcode{typename Context::template formatter_type>}\linebreak{} meets the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements} for each $\tcode{T}_i$ in \tcode{Args}. @@ -17277,6 +17313,9 @@ basic_format_arg get(size_t i) const noexcept; }; + + template + basic_format_args(@\exposid{format-arg-store}@) -> basic_format_args; } \end{codeblock} @@ -17346,9 +17385,9 @@ basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@(")"); // \expos public: - constexpr void set_separator(basic_string_view sep); + constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, - basic_string_view closing); + basic_string_view closing) noexcept; template constexpr typename ParseContext::iterator @@ -17427,7 +17466,7 @@ \indexlibrarymember{set_separator}{formatter}% \begin{itemdecl} -constexpr void set_separator(basic_string_view sep); +constexpr void set_separator(basic_string_view sep) noexcept; \end{itemdecl} \begin{itemdescr} @@ -17438,7 +17477,8 @@ \indexlibrarymember{set_brackets}{formatter}% \begin{itemdecl} -constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +constexpr void set_brackets(basic_string_view opening, + basic_string_view closing) noexcept; \end{itemdecl} \begin{itemdescr} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index d001fc93d8..b124de5d68 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -110,5 +110,9 @@ \movedxref{expos.only.func}{expos.only.entity} \removedxref{expos.only.types} +% P2614R2 Deprecate numeric_limits::has_denorm +\movedxref{denorm.style}{depr.numeric.limits.has.denorm} +\removedxref{fp.style} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref) diff --git a/tools/check-source.sh b/tools/check-source.sh index 415f6221d3..3af7f80691 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -189,6 +189,13 @@ for f in $texfiles; do done | fail '"shall", "should", or "may" inside a note' || failed=1 +# Comma after e.g. and i.e. +grep -n "e\.g\.[^,]" $texfiles | + fail '"e.g." must be followed by a comma' +grep -n "i\.e\.[^,]" $texfiles | + fail '"i.e." must be followed by a comma' + + # \logop should use lowercase arguments grep -n '\\logop{[^}]*[^andor}][^}]*}' $texfiles | fail 'bad argument for \\logop' || failed=1