diff --git a/.gitignore b/.gitignore index bfe502c1da..bcaa1569dd 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ std-gram.ext .tags_sorted_by_file tools/sections *.synctex.gz +*.synctex* diff --git a/papers/n4810.pdf b/papers/n4810.pdf new file mode 100644 index 0000000000..00eb319796 Binary files /dev/null and b/papers/n4810.pdf differ diff --git a/papers/n4811.html b/papers/n4811.html new file mode 100644 index 0000000000..bd7f20b7b7 --- /dev/null +++ b/papers/n4811.html @@ -0,0 +1,808 @@ +N4811 +

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

+ +

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

+ +

Acknowledgements

+ +

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

+ + + +

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

+ +

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

+ +

New papers

+ + + +

Motions incorporated into working draft

+ +

Core working group motions

+ +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

CWG motion 11: P1103R3 "Modules"

+ +

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

+ +

CWG motions 13 and 14 apply to the Reflection TS

+ +

CWG motion 15: P0912R5 "Coroutines"

+ +

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

+ +

Library working group motions

+ +

LWG motion 1 applies to the Library Fundamentals TS

+ +

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

+ + + +

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

+ +

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

+ +

LWG motion 5 was retracted

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

LWG motion 16: P1252R2 "Ranges design cleanup"

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Notable editorial changes

+ +

CWG motion 1

+ +

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

+ +

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

+ +

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

+ +

CWG motion 2

+ +

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

+ +

CWG motion 12

+ +

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

+ +

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

+ +

CWG motion 15

+ +

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

+ +

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

+ +

LWG motion 2

+ +

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

+ +

Section label changes

+ +

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

+ +

Reversion of prior editorial change

+ +

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

+ +

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

+ +

Minor editorial fixes

+ +

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

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

` with the right promise type `P`. + +### LWG motion 2 + +Replaced the references to *CopyConstructible* and *CopyAssignable* with the +intended *Cpp17CopyConstructible* and *Cpp17CopyAssignable* after consultation +with LWG. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, all section labels containing underscores have been renamed +to instead use periods. + +### Reversion of prior editorial change + +In N4791 (the post-San-Diego working draft), an editorial change was applied +to repair missing wording in 2018-11 CWG motion 14 +([P0595R2 "`std::is_constant_evaluated()`"](http://wg21.link/p0595r2)). +This change added a definition of the term "usable in constant expressions" +as applied to objects and references that was inadvertantly dropped from the +wording during CWG review. + +Further review within CWG has shown that the dropped wording is also incorrect, +so the editorial fix has been reverted (leaving the definition absent rather +than incorrect), and a proper definition will be inserted by a core issue. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4800 is below. +This list excludes changes +that do not affect the body text or only affect whitespace or typeface. For a +complete list including such changes (or for the actual deltas applied by these +changes), consult the [draft sources on github](https://github.com/cplusplus/draft/compare/n4800...n4810). + + commit 142acf0bbde8d6fd20cb67c051d896fec33a84b6 + Author: stryku + Date: Thu Oct 11 18:41:18 2018 +0200 + + [decl.init]/10 Fix specified initialization. + + According to [basic.start.static]/2, for objects with static storage duration, + zero initialization performs only if constant initialization does not. + [decl.init]/10 can be generalized to static initialization. + This is an editorial note change. + + commit 74def77454a15b6cdb45be0f31916396b4b63b72 + Author: Richard Smith + Date: Fri Mar 15 13:45:06 2019 -0700 + + [util.smartptr.atomic.shared] [util.smartptr.atomic.weak] Clarify + grouping of "either". + + commit 4c5701a79cc7c4cc7b9cd9c6070e3cd88961aca7 + Author: Jens Maurer + Date: Fri Dec 21 21:04:43 2018 +0100 + + [mismatch] LWG3178 std::mismatch is missing an upper bound + + commit 04a5e31a02e19e5d1c9e9a0b05c40ce8730c7064 + Author: Jens Maurer + Date: Sat Jan 26 00:30:13 2019 +0100 + + [algorithms] Qualify declarator-id with sub-namespace. + + Also qualify return types where appropriate. + + commit 6c844190a533950fc0100eac4da7785d99c87400 + Author: Jens Maurer + Date: Fri Mar 15 20:25:59 2019 +0100 + + [time.clock.req] Change 'satisfy' to 'meet'. + + commit c3adaef44b94cc63a8a8806f398185046461947c + Author: Jens Maurer + Date: Fri Mar 15 19:23:30 2019 +0100 + + [numeric.requirements] Define 'numeric type'. + + commit 1ce86a62a3cff9fb2bcf6c1a2c37168e023e338b + Author: Jens Maurer + Date: Sat Mar 9 22:18:26 2019 +0100 + + [time.clock.req] Simplify requirements for Cpp17TrivialClock. + + commit 0ba5424c1beddfd8c8403ce882b96dee0f530c7f + Author: JF Bastien + Date: Fri Mar 15 13:52:39 2019 -0700 + + [basic.fundamental] Rename 'range exponent' to 'width' to align with C + + commit 9e00558f2a824421406a6703d1232cc4fb89bb15 + Author: Arthur O'Dwyer + Date: Fri Mar 15 16:43:16 2019 -0400 + + [std] Fix a bunch of faulty parallelism with "either". + + commit 54ddcb970132bfe026c9d9d62d967632b56ae303 + Author: BRevzin + Date: Fri Mar 15 15:30:07 2019 -0500 + + [class.rel] Simplifying wording to avoid talking about a reversed <=>. + + We can never select a reversed <=> here because the operands are of the same type. + + commit 5d174b05d8cd08717ed7efc05d0271409651071c + Author: Richard Smith + Date: Fri Mar 15 12:33:42 2019 -0700 + + [expr.prim.lambda.capture] Convert paragraphs repeating the + "non-odr-usable local entities shall not be odr-used" rule from + [basic.def.odr] into notes. + + commit 41853024e5e6fcd5feb496f64767d2888d76154f + Author: Richard Smith + Date: Fri Mar 15 11:38:57 2019 -0700 + + Revert "[expr.const] Add missing definition of 'usable in constant expressions'" + + The prior editorial fix was an attempt to re-add wording that was + missing from P0595R2 (moved as 2018-11 CWG Motion 14). However, CWG + analysis has indicated that the editorial fix is incomplete, so we're + reverting it to restore the wording to the as-moved state. + + This reverts commit e58439bce8af85e6569328272c2cfb73f5fc44d6. + + commit 154f2c59c4377897937f4b0722cfe2b6d726cc59 + Author: birbacher + Date: Fri Mar 15 18:39:16 2019 +0000 + + [container.node] Add 3 "template" keywords for dependent name (#2676) + + On: + [container.node.overview]/4 + [container.node.cons]/3.1 + [container.node.dtor]/1 + + commit 2585d7f5894b46e0aa2f961183060a5201b2cca7 + Author: Jens Maurer + Date: Fri Dec 21 19:29:38 2018 +0100 + + [std] Replace underscores in stable labels with periods. + + commit 554a8926404bd5e0f772a6cb72c04bd12a5b7984 + Author: Casey Carter + Date: Mon Mar 4 09:29:50 2019 -0800 + + [specialized.algorithms] Rename voidify's parameter + + `ptr` is an odd name for a parameter that is a reference to storage for an object. + + commit a2dfa61a0d50a24e7be6cbc004bb0f076b8c62b5 + Author: Jens Maurer + Date: Fri Mar 8 22:25:38 2019 +0100 + + [queue.syn,stack.syn] Add partial specialization of uses_allocator + + commit 721f2d606f90cc20a16ad9b4383bc78cb368abdc + Author: Jonathan Wakely + Date: Fri Mar 15 02:53:18 2019 +0000 + + [func.not_fn], [func.bind_front] fix phrasing of \mandates and \expects (#2750) + + The Mandates: element should just state its condition, and not say "shall". + Cpp17 concept requirements should be phrased as "X meets the + Y requirements" not "X shall meet the requirements of Y". + + commit 48484c967ee5f3ecb65ff857f8f4794e108ba0cb + Author: Krystian + Date: Thu Mar 14 22:49:33 2019 -0400 + + [temp.class.spec.mfunc] Correct "class template specialization" to the intended "class template partial specialization" + + commit 3117814eaf800a5e1dd387f4c5a0522f2627689e + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Mar 15 05:48:28 2019 +0300 + + [expr.sizeof] Remove the redundant paragraph 3 + + Paragraph 1 already says that functions are disallowed and function pointers are allowed. + + commit c769f835dadd4a35df9febad684a296d6cb71a53 + Author: JF Bastien + Date: Thu Mar 14 19:45:53 2019 -0700 + + [dcl.attr.contract.cond] Replace return type with 'void' in example that does not return + + Also remove the (unused) name for the return value in the postcondition. + + commit d48c79e223cfbd5ec134703e20989235208e9364 + Author: Jens Maurer + Date: Fri Mar 8 01:14:16 2019 +0100 + + [dcl.enum] Fix singular/plural mismatch. + + commit c5fb73ba6a9b71f6e247103ab4baac1c9f72e210 + Author: Jens Maurer + Date: Fri Mar 8 01:13:35 2019 +0100 + + [conv.prom] b_min and b_max are no longer defined in [dcl.enum] + + commit d7d2580c7d8fabe25ada4dd0e091f9997c0916f5 + Author: Jens Maurer + Date: Sat Mar 9 22:36:47 2019 +0100 + + [range.iota,range.adaptors] Add cross-references for private member types. + + commit b8fd249c737ff2c3652cf6ef77db25712038d353 + Author: Jens Maurer + Date: Sun Mar 10 20:20:10 2019 +0100 + + [dcl.init] Prepend 'Otherwise' to a bullet + + commit dd227824ade24ab51dd4cc926c4b9e87cc29becf + Author: Jens Maurer + Date: Sun Mar 10 20:28:41 2019 +0100 + + [dcl.attr.contract.cond] References cannot be modified. + + Avoid confusion caused by using the words "makes [...] + modifications of the value of [a] parameter" by excluding + references. + + commit b0116b87bf33fed9648e6e8b1b0c7cee0d90b311 + Author: Jason Merrill + Date: Tue Mar 12 09:06:23 2019 -0400 + + [over.match.best] Add number for paragraph 2. + + commit f0f7ba234644d3690d18fcba73f618648014a47c + Author: Jens Maurer + Date: Wed Mar 13 22:21:42 2019 +0100 + + [lib] Use '(inclusive)', not other punctuation + + to indicate inclusive ranges in prose. + + commit 5ba461ec9836f95ed7a54b563b06d480f564e987 + Author: Jens Maurer + Date: Wed Mar 13 22:46:19 2019 +0100 + + [class.eq,class.spaceship] Clarify order of comparison. + + commit 42e5df5c08c9ef805da304fe05fe387cfc3d33d5 + Author: Jens Maurer + Date: Thu Mar 14 00:02:25 2019 +0100 + + [basic.lookup.argdep] Reorder bullets to group semantics. + + commit 927dc13e1010e031692f3a94d8e9599beeb877ac + Author: Richard Smith + Date: Thu Mar 14 17:22:07 2019 -0700 + + [array.tuple] Fix broken description of tuple_element for std::array. + + commit 0b06fcd5f92bc0439a868471a5fdfdba8a181941 + Author: Jens Maurer + Date: Fri Mar 8 22:12:14 2019 +0100 + + [ranges.syn] Add ref_view to header synopsis. + + commit 6f6e5772b2a2dcf41e3db4f68b6cbc3c0628c061 + Author: Richard Smith + Date: Thu Mar 14 16:05:33 2019 -0700 + + [algorithms.parallel.exec] Rephrase to avoid incorrect use of "may not". + + Convert rationale sentence to a note. + + commit de76c7de8c4f9734e0e4351d2088d4786ee62135 + Author: Jens Maurer + Date: Tue Mar 5 21:57:10 2019 +0100 + + [char.traits.typedefs] Change 'shall meet' to 'meets' + + commit e11e27a7873953f0c078901f7ddbb0d7d701c5f7 + Author: Jens Maurer + Date: Wed Mar 6 21:15:37 2019 +0100 + + [mem.poly.allocator.mem] Avoid duplicate colons. + + commit 2956ba37186d7e9cbe728cc3870a2a26fb1f0168 + Author: Richard Smith + Date: Wed Mar 13 14:14:43 2019 -0700 + + [dcl.fct.def.coroutine] Update wording to align with current editorial + conventions. + + Reorder and rearrange to reduce the number of variables with long scopes + that we define in the wording. + + Fix mismatch between core and library wording where library permits + coroutine_handle to resume a coroutine with any promise type, and + the core language does not. + + commit 8dd4539b24473677809163f5e6d399ba6aa0b27d + Author: Richard Smith + Date: Tue Mar 12 18:15:59 2019 -0700 + + [expr.await] Rephrase and modernize wording. + + Invoke temporary materialization conversion directly rather than + handwaving about a temporary object. Specify that the o expression is + evaluated. Bulletize description of the three different ways that + await-suspend is called. + + Fix wording that uses values and objects on the left-hand side of a + class member access to instead consistently use expressions. + + Fixes #2774. + + commit d69814f61077f7e549ccc39a21fc3b90db4223d6 + Author: Richard Smith + Date: Mon Mar 11 20:12:17 2019 -0700 + + [temp.param] "a type that is literal" -> "a literal type". + + commit c0058816fdfe079095ca8717ad692dc2d498d6a3 + Author: Richard Smith + Date: Mon Mar 11 20:11:46 2019 -0700 + + [class.eq] Remove redundant repetition of the operator== symmetry rule. + + commit 007c0c1a619417f94c2c4efb57be71c09f2c2870 + Author: Jens Maurer + Date: Wed Mar 6 21:32:09 2019 +0100 + + [temp.type] Do not refer to operator==, which excludes built-in ==. + + commit caa5c8aedecdf68cfda4f5d95ec9d20451953117 + Author: Jens Maurer + Date: Tue Mar 5 19:05:25 2019 +0100 + + [class.compare.default] Add a note that friends are found by ADL only. + + commit c9074b533c835bbf820f5ea09957810ed2c04dab + Author: Jens Maurer + Date: Wed Mar 6 20:56:58 2019 +0100 + + [expr.new] Move treatment of arrays of unknown bound + + commit ce2f08ab94123adb44e58f1176c6ae4f3209eb60 + Author: Richard Smith + Date: Mon Mar 11 17:20:25 2019 -0700 + + [dcl.init] Merge new direct aggregate init wording into class direct + initialization bullet to avoid the wording being unreachable due to an + "Otherwise" chain. + + commit 691b7c10530d3265afbf445dff3dd129c7c5692e + Author: Dawn Perchik + Date: Sun Mar 10 16:15:53 2019 -0700 + + [dcl.init] Moved the changed bullet in 17.5 to before 17.6.3. + + commit 5f7461d24bc0e9867458a043adf04aa8c4ceed73 + Author: Richard Smith + Date: Fri Mar 8 16:11:34 2019 -0800 + + [temp.dep.type] Rephrase to avoid suggesting that an expression can be + the current instantiation. + + A type can't be the current instantiation either, but that's a + pre-existing prevalent problem. + + commit cbb21fb0210b6aade5591de94e3a27d7059e9d06 + Author: Richard Smith + Date: Fri Mar 8 16:08:02 2019 -0800 + + [basic.def.odr] Apply additional edits from CWG review that were not + transcribed into P1359R0. + + commit ac732bfe4eef01e9e2443dac6138270695d7cbf9 + Author: Richard Smith + Date: Fri Mar 8 12:24:49 2019 -0800 + + [expr.prim.lambda.capture] Add missing close parentheses in CWG2358 + examples. + + Fixes #2680. + + commit 502e419ca75c9656394d1998036b4b810e8bdb17 + Author: Richard Smith + Date: Fri Mar 8 12:00:26 2019 -0800 + + [dcl.type.simple] Fix inaccurate note added by CWG2332 + + [temp.local] Clarify that the surrounding syntax and construct directly + dictates whether an injected-class-name is syntactically a template-name + or a type-name, not just what it means. + + commit f4346ece403e469e800d635a75baafb9c411aa1b + Author: Richard Smith + Date: Fri Mar 8 11:39:36 2019 -0800 + + [expr.static.cast] Fix wording of CWG2310 to match CWG intent (verified + on core reflector): + + - in p11, require D to be a complete class type, not B + - in p12, rephrase to avoid the suggestion that we're talking about a + different D than the one already in scope + + commit 6f34b0513ed6d974b86a27429f8f4d02a6c18b88 + Author: Hana Dusíková + Date: Fri Feb 22 11:03:29 2019 -1000 + + [pair.astuple, tuple.helper] Fix inconsistent class key in tuple_size/tuple_element. (#2679) + + It was declared as a struct and specializations were classes. + + commit 102a791b446f70f939a9b1e2e66fc3553aade19c + Author: Johel Ernesto Guerrero Peña + Date: Fri Feb 22 02:30:23 2019 -0400 + + [array.syn] Add reference to [array.tuple] + + commit 7fe655909b4e5f01d8a8b71d6b508785c42c739e + Author: Richard Smith + Date: Wed Feb 20 17:04:55 2019 -1000 + + [temp.dep] [temp.dep.res] Remove redundant restatement of the two-phase + lookup rule. The primary location of the rule is [temp.dep.candidate]. + + commit 8fbeb52ae5daccc0352798ff023f6cba6aebcd42 + Author: Richard Smith + Date: Mon Feb 18 17:15:39 2019 -1000 + + [basic.link] The notion of the linkage of a type is no longer used for + any purpose. Remove it and move its example next to the rule that + justifies it, and simplify said example. + + commit cafdbd8036f3cf19e9cfc2f56584b219fb190602 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Jan 25 00:12:44 2019 +0300 + + [expr.sizeof]/2: there are no expressions of reference type + + commit 35ce0ae2eb2582dbc00fc824afbfa1d53a64de8d + Author: Richard Smith + Date: Wed Feb 13 17:51:58 2019 -0800 + + [depr.array.comp] Fix example of deprecated array comparison + + commit 2f0bd979f41953890129fcbdc6ef37e3e90387ad + Author: Alisdair Meredith + Date: Sun Feb 10 16:53:15 2019 -0500 + + Add missing noexcept cross-refs for invokable traits (#2662) + + All the other traits that use the phrase 'is known not to throw exceptions' also cross-reference the core clause for the noexcept operator, so add the missing cross reference to the more recently added traits. + + commit 9f261368736c3666791329145292c1563a291861 + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Sun Feb 10 22:52:36 2019 +0100 + + [temp.mem.func] Fixed text in example, which was not updated by CWG 249 (#2658) + + commit f668df034ebf27ad53b5addad22af4f1293f829f + Author: Jens Maurer + Date: Sun Feb 10 22:50:42 2019 +0100 + + [algorithms.general,concepts.general] Add missing entries for summary tables (#2663) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4b61488ff1..5434dfa69c 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -16,11 +16,13 @@ as summarized in \tref{algorithms.summary}. \begin{libsumtab}{Algorithms library summary}{tab:algorithms.summary} +\ref{algorithms.requirements} & Algorithms requirements & \\ +\ref{algorithms.parallel} & Parallel algorithms & \\ \hline \ref{alg.nonmodifying} & Non-modifying sequence operations & \\ \ref{alg.modifying.operations} & Mutating sequence operations & \tcode{} \\ \ref{alg.sorting} & Sorting and related operations & \\ \hline \ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep -\ref{alg.c.library} & C library algorithms & \tcode{} \\ \hline +\ref{alg.c.library} & C library algorithms & \tcode{} \\ \end{libsumtab} \rSec1[algorithms.requirements]{Algorithms requirements} @@ -311,6 +313,35 @@ \end{itemize} \end{example} +\pnum +A standard library function is \defn{vectorization-unsafe} +if it is specified to synchronize with another function invocation, or +another function invocation is specified to synchronize with it, +and if it is not a memory allocation or deallocation function. +\begin{note} +Implementations must ensure that internal synchronization +inside standard library functions does not prevent forward progress +when those functions are executed by threads of execution +with weakly parallel forward progress guarantees. +\end{note} +\begin{example} +\begin{codeblock} +int x = 0; +std::mutex m; +void f() { + int a[] = {1,2}; + std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) { + std::lock_guard guard(m); // incorrect: \tcode{lock_guard} constructor calls \tcode{m.lock()} + ++x; + }); +} +\end{codeblock} +The above program may result in two consecutive calls to \tcode{m.lock()} +on the same thread of execution (which may deadlock), +because the applications of the function object are not guaranteed +to run on different threads of execution. +\end{example} + \rSec2[algorithms.parallel.user]{Requirements on user-provided function objects} \pnum @@ -376,11 +407,34 @@ The invocations are not interleaved; see~\ref{intro.execution}. \end{note} +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::unsequenced_policy} +are permitted to execute in an unordered fashion +in the calling thread of execution, +unsequenced with respect to one another in the calling thread of execution. +\begin{note} +This means that multiple function object invocations +may be interleaved on a single thread of execution, +which overrides the usual guarantee from \ref{intro.execution} +that function executions do not overlap with one another. +\end{note} +The behavior of a program is undefined if +it invokes a vectorization-unsafe standard library function +from user code +called from a \tcode{execution::unsequenced_policy} algorithm. +\begin{note} +Because \tcode{execution::unsequenced_policy} allows +the execution of element access functions +to be interleaved on a single thread of execution, +blocking synchronization, including the use of mutexes, risks deadlock. +\end{note} + \pnum The invocations of element access functions in parallel algorithms invoked with an execution policy object of type \tcode{execution::parallel_policy} -are permitted to execute -in either the invoking thread of execution or +are permitted to execute either +in the invoking thread of execution or in a thread of execution implicitly created by the library to support parallel algorithm execution. If the threads of execution created by \tcode{thread}\iref{thread.thread.class} @@ -437,7 +491,7 @@ \pnum The invocations of element access functions in parallel algorithms invoked with -an execution policy of type \tcode{execution::parallel_unsequenced_policy} are +an execution policy object of type \tcode{execution::parallel_unsequenced_policy} are permitted to execute in an unordered fashion in unspecified threads of execution, and unsequenced with respect to one another within each thread of execution. @@ -449,48 +503,28 @@ This means that multiple function object invocations may be interleaved on a single thread of execution, which overrides the usual guarantee from \ref{intro.execution} -that function executions do not interleave with one another. +that function executions do not overlap with one another. \end{note} -Since \tcode{execution::parallel_unsequenced_policy} allows +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. +\begin{note} +Because \tcode{execution::parallel_unsequenced_policy} allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock. -Thus, the synchronization with \tcode{execution::parallel_unsequenced_policy} -is restricted as follows: -A standard library function is \defn{vectorization-unsafe} -if it is specified to synchronize with another function invocation, or -another function invocation is specified to synchronize with it, and -if it is not a memory allocation or deallocation function. -Vectorization-unsafe standard library functions may not be invoked by user code -called from \tcode{execution::parallel_unsequenced_policy} algorithms. -\begin{note} -Implementations must ensure -that internal synchronization inside standard library functions -does not prevent forward progress -when those functions are executed -by threads of execution with weakly parallel forward progress guarantees. \end{note} -\begin{example} -\begin{codeblock} -int x = 0; -std::mutex m; -int a[] = {1,2}; -std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) { - std::lock_guard guard(m); // incorrect: \tcode{lock_guard} constructor calls \tcode{m.lock()} - ++x; -}); -\end{codeblock} -The above program may result in two consecutive calls to \tcode{m.lock()} -on the same thread of execution (which may deadlock), -because the applications of the function object are not guaranteed -to run on different threads of execution. -\end{example} + +\pnum \begin{note} -The semantics of the \tcode{execution::parallel_policy} or -the \tcode{execution::parallel_unsequenced_policy} invocation +The semantics of invocation with +\tcode{execution::unsequenced_policy}, +\tcode{execution::parallel_policy}, or +\tcode{execution::parallel_unsequenced_policy} allow the implementation to fall back to sequential execution -if the system cannot parallelize an algorithm invocation -due to lack of resources. +if the system cannot parallelize an algorithm invocation, +e.g., due to lack of resources. \end{note} \pnum @@ -575,7 +609,7 @@ namespace std { // \ref{alg.nonmodifying}, non-modifying sequence operations - // \ref{alg.all_of}, all of + // \ref{alg.all.of}, all of template constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); template @@ -591,7 +625,7 @@ constexpr bool all_of(R&& r, Pred pred, Proj proj = {}); } - // \ref{alg.any_of}, any of + // \ref{alg.any.of}, any of template constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); template @@ -607,7 +641,7 @@ constexpr bool any_of(R&& r, Pred pred, Proj proj = {}); } - // \ref{alg.none_of}, none of + // \ref{alg.none.of}, none of template constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); template @@ -633,8 +667,20 @@ namespace ranges { template struct for_each_result { - I in; - F fun; + [[no_unique_address]] I in; + [[no_unique_address]] F fun; + + template + requires ConvertibleTo && ConvertibleTo + operator for_each_result() const & { + return {in, fun}; + } + + template + requires ConvertibleTo && ConvertibleTo + operator for_each_result() && { + return {std::move(in), std::move(fun)}; + } }; template S, class Proj = identity, @@ -678,10 +724,10 @@ namespace ranges { template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> + requires IndirectRelation, const T*> constexpr I find(I first, S last, const T& value, Proj proj = {}); template - requires IndirectRelation, projected, Proj>, const T*> + requires IndirectRelation, Proj>, const T*> constexpr safe_iterator_t find(R&& r, const T& value, Proj proj = {}); template S, class Proj = identity, @@ -725,13 +771,13 @@ namespace ranges { template S1, ForwardIterator I2, Sentinel S2, - class Pred = ranges::equal_to<>, class Proj1 = identity, class Proj2 = identity> + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> requires IndirectlyComparable constexpr subrange find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, class Proj1 = identity, class Proj2 = identity> + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr safe_subrange_t find_end(R1&& r1, R2&& r2, Pred pred = {}, @@ -765,13 +811,13 @@ template S1, ForwardIterator I2, Sentinel S2, class Proj1 = identity, class Proj2 = identity, IndirectRelation, - projected> Pred = ranges::equal_to<>> + projected> Pred = ranges::equal_to> constexpr I1 find_first_of(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, Proj1>, - projected, Proj2>> Pred = ranges::equal_to<>> + projected, Proj2>> Pred = ranges::equal_to> constexpr safe_iterator_t find_first_of(R1&& r1, R2&& r2, Pred pred = {}, @@ -798,11 +844,11 @@ namespace ranges { template S, class Proj = identity, - IndirectRelation> Pred = ranges::equal_to<>> + IndirectRelation> Pred = ranges::equal_to> constexpr I adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); template, Proj>> Pred = ranges::equal_to<>> + IndirectRelation, Proj>> Pred = ranges::equal_to> constexpr safe_iterator_t adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); } @@ -825,11 +871,11 @@ namespace ranges { template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> + requires IndirectRelation, const T*> constexpr iter_difference_t count(I first, S last, const T& value, Proj proj = {}); template - requires IndirectRelation, projected, Proj>, const T*> + requires IndirectRelation, Proj>, const T*> constexpr iter_difference_t> count(R&& r, const T& value, Proj proj = {}); template S, class Proj = identity, @@ -887,21 +933,33 @@ namespace ranges { template struct mismatch_result { - I1 in1; - I2 in2; + [[no_unique_address]] I1 in1; + [[no_unique_address]] I2 in2; + + template + requires ConvertibleTo && ConvertibleTo + operator mismatch_result() const & { + return {in1, in2}; + } + + template + requires ConvertibleTo && ConvertibleTo + operator mismatch_result() && { + return {std::move(in1), std::move(in2)}; + } }; template S1, InputIterator I2, Sentinel S2, class Proj1 = identity, class Proj2 = identity, IndirectRelation, - projected> Pred = ranges::equal_to<>> + projected> Pred = ranges::equal_to> constexpr mismatch_result mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, Proj1>, - projected, Proj2>> Pred = ranges::equal_to<>> + projected, Proj2>> Pred = ranges::equal_to> constexpr mismatch_result, safe_iterator_t> mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); @@ -943,19 +1001,19 @@ namespace ranges { template S1, InputIterator I2, Sentinel S2, - class Pred = ranges::equal_to<>, class Proj1 = identity, class Proj2 = identity> + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> requires IndirectlyComparable constexpr bool equal(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, + template requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr bool equal(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); } - // \ref{alg.is_permutation}, is permutation + // \ref{alg.is.permutation}, is permutation template constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); @@ -972,13 +1030,13 @@ namespace ranges { template S1, ForwardIterator I2, - Sentinel S2, class Pred = ranges::equal_to<>, class Proj1 = identity, + Sentinel S2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> requires IndirectlyComparable constexpr bool is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, + template requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr bool is_permutation(R1&& r1, R2&& r2, Pred pred = {}, @@ -1010,13 +1068,13 @@ namespace ranges { template S1, ForwardIterator I2, - Sentinel S2, class Pred = ranges::equal_to<>, + Sentinel S2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> requires IndirectlyComparable constexpr subrange search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, + template requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr safe_subrange_t @@ -1048,12 +1106,12 @@ namespace ranges { template S, class T, - class Pred = ranges::equal_to<>, class Proj = identity> + class Pred = ranges::equal_to, class Proj = identity> requires IndirectlyComparable constexpr subrange search_n(I first, S last, iter_difference_t count, const T& value, Pred pred = {}, Proj proj = {}); - template, + template requires IndirectlyComparable, const T*, Pred, Proj> constexpr safe_subrange_t @@ -1078,8 +1136,20 @@ namespace ranges { template struct copy_result { - I in; - O out; + [[no_unique_address]] I in; + [[no_unique_address]] O out; + + template + requires ConvertibleTo && ConvertibleTo + operator copy_result() const & { + return {in, out}; + } + + template + requires ConvertibleTo && ConvertibleTo + operator copy_result() && { + return {std::move(in), std::move(out)}; + } }; template S, WeaklyIncrementable O> @@ -1266,9 +1336,23 @@ template struct binary_transform_result { - I1 in1; - I2 in2; - O out; + [[no_unique_address]] I1 in1; + [[no_unique_address]] I2 in2; + [[no_unique_address]] O out; + + template + requires ConvertibleTo && + ConvertibleTo && ConvertibleTo + operator binary_transform_result() const & { + return {in1, in2, out}; + } + + template + requires ConvertibleTo && + ConvertibleTo && ConvertibleTo + operator binary_transform_result() && { + return {std::move(in1), std::move(in2), std::move(out)}; + } }; template S1, InputIterator I2, Sentinel S2, @@ -1307,12 +1391,12 @@ namespace ranges { template S, class T1, class T2, class Proj = identity> requires Writable && - IndirectRelation, projected, const T1*> + IndirectRelation, const T1*> constexpr I replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template requires Writable, const T2&> && - IndirectRelation, projected, Proj>, const T1*> + IndirectRelation, Proj>, const T1*> constexpr safe_iterator_t replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); template S, class T, class Proj = identity, @@ -1353,14 +1437,14 @@ template S, class T1, class T2, OutputIterator O, class Proj = identity> requires IndirectlyCopyable && - IndirectRelation, projected, const T1*> + IndirectRelation, const T1*> constexpr replace_copy_result replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, Proj proj = {}); template O, class Proj = identity> requires IndirectlyCopyable, O> && - IndirectRelation, projected, Proj>, const T1*> + IndirectRelation, Proj>, const T1*> constexpr replace_copy_result, O> replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, Proj proj = {}); @@ -1448,11 +1532,11 @@ namespace ranges { template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> + requires IndirectRelation, const T*> constexpr I remove(I first, S last, const T& value, Proj proj = {}); template requires Permutable> && - IndirectRelation, projected, Proj>, const T*> + IndirectRelation, Proj>, const T*> constexpr safe_iterator_t remove(R&& r, const T& value, Proj proj = {}); template S, class Proj = identity, @@ -1493,12 +1577,12 @@ template S, WeaklyIncrementable O, class T, class Proj = identity> requires IndirectlyCopyable && - IndirectRelation, projected, const T*> + IndirectRelation, const T*> constexpr remove_copy_result remove_copy(I first, S last, O result, const T& value, Proj proj = {}); template requires IndirectlyCopyable, O> && - IndirectRelation, projected, Proj>, const T*> + IndirectRelation, Proj>, const T*> constexpr remove_copy_result, O> remove_copy(R&& r, O result, const T& value, Proj proj = {}); @@ -1533,10 +1617,10 @@ namespace ranges { template S, class Proj = identity, - IndirectRelation> C = ranges::equal_to<>> + IndirectRelation> C = ranges::equal_to> constexpr I unique(I first, S last, C comp = {}, Proj proj = {}); template, Proj>> C = ranges::equal_to<>> + IndirectRelation, Proj>> C = ranges::equal_to> requires Permutable> constexpr safe_iterator_t unique(R&& r, C comp = {}, Proj proj = {}); @@ -1567,7 +1651,7 @@ using unique_copy_result = copy_result; template S, WeaklyIncrementable O, - class Proj = identity, IndirectRelation> C = ranges::equal_to<>> + class Proj = identity, IndirectRelation> C = ranges::equal_to> requires IndirectlyCopyable && (ForwardIterator || (InputIterator && Same, iter_value_t>) || @@ -1575,7 +1659,7 @@ constexpr unique_copy_result unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); template, Proj>> C = ranges::equal_to<>> + IndirectRelation, Proj>> C = ranges::equal_to> requires IndirectlyCopyable, O> && (ForwardIterator> || (InputIterator && Same>, iter_value_t>) || @@ -1729,12 +1813,12 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I sort(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t sort(R&& r, Comp comp = {}, Proj proj = {}); @@ -1754,11 +1838,11 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable I stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> safe_iterator_t stable_sort(R&& r, Comp comp = {}, Proj proj = {}); @@ -1784,12 +1868,12 @@ RandomAccessIterator last, Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t partial_sort(R&& r, iterator_t middle, Comp comp = {}, @@ -1824,13 +1908,13 @@ namespace ranges { template S1, RandomAccessIterator I2, Sentinel S2, - class Comp = ranges::less<>, class Proj1 = identity, class Proj2 = identity> + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires IndirectlyCopyable && Sortable && IndirectStrictWeakOrder, projected> constexpr I2 partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, + template requires IndirectlyCopyable, iterator_t> && Sortable, Comp, Proj2> && @@ -1856,10 +1940,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr bool is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr bool is_sorted(R&& r, Comp comp = {}, Proj proj = {}); } @@ -1882,10 +1966,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr safe_iterator_t is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); } @@ -1907,12 +1991,12 @@ RandomAccessIterator last, Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); @@ -1930,12 +2014,12 @@ namespace ranges { template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I lower_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = - ranges::less<>> + ranges::less> constexpr safe_iterator_t lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); } @@ -1951,11 +2035,11 @@ namespace ranges { template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = - ranges::less<>> + ranges::less> constexpr safe_iterator_t upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); } @@ -1971,12 +2055,12 @@ namespace ranges { template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr subrange equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = - ranges::less<>> + ranges::less> constexpr safe_subrange_t equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); } @@ -1992,12 +2076,12 @@ namespace ranges { template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr bool binary_search(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = - ranges::less<>> + ranges::less> constexpr bool binary_search(R&& r, const T& value, Comp comp = {}, Proj proj = {}); } @@ -2078,9 +2162,23 @@ namespace ranges { template struct partition_copy_result { - I in; - O1 out1; - O2 out2; + [[no_unique_address]] I in; + [[no_unique_address]] O1 out1; + [[no_unique_address]] O2 out2; + + template + requires ConvertibleTo && + ConvertibleTo && ConvertibleTo + operator partition_copy_result() const & { + return {in, out1, out2}; + } + + template + requires ConvertibleTo && + ConvertibleTo && ConvertibleTo + operator partition_copy_result() && { + return {std::move(in), std::move(out1), std::move(out2)}; + } }; template S, WeaklyIncrementable O1, WeaklyIncrementable O2, @@ -2145,13 +2243,13 @@ using merge_result = binary_transform_result; template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, class Proj1 = identity, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable constexpr merge_result merge(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, + template requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> constexpr merge_result, safe_iterator_t, O> @@ -2179,11 +2277,11 @@ BidirectionalIterator last, Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> safe_iterator_t inplace_merge(R&& r, iterator_t middle, Comp comp = {}, @@ -2213,13 +2311,13 @@ template S1, InputIterator I2, Sentinel S2, class Proj1 = identity, class Proj2 = identity, IndirectStrictWeakOrder, projected> Comp = - ranges::less<>> + ranges::less> constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, Proj1>, - projected, Proj2>> Comp = ranges::less<>> + projected, Proj2>> Comp = ranges::less> constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); } @@ -2254,14 +2352,14 @@ using set_union_result = binary_transform_result; template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable constexpr set_union_result set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, class Proj1 = identity, class Proj2 = identity> + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> constexpr set_union_result, safe_iterator_t, O> set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, @@ -2298,14 +2396,14 @@ using set_intersection_result = binary_transform_result; template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable constexpr set_intersection_result set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, class Proj1 = identity, class Proj2 = identity> + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> constexpr set_intersection_result, safe_iterator_t, O> set_intersection(R1&& r1, R2&& r2, O result, @@ -2342,14 +2440,14 @@ using set_difference_result = copy_result; template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable constexpr set_difference_result set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, class Proj1 = identity, class Proj2 = identity> + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> constexpr set_difference_result, O> set_difference(R1&& r1, R2&& r2, O result, @@ -2386,7 +2484,7 @@ using set_symmetric_difference_result = binary_transform_result; template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable constexpr set_symmetric_difference_result @@ -2394,7 +2492,7 @@ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, class Proj1 = identity, class Proj2 = identity> + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> constexpr set_symmetric_difference_result, safe_iterator_t, O> set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, @@ -2409,12 +2507,12 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I push_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t push_heap(R&& r, Comp comp = {}, Proj proj = {}); @@ -2427,12 +2525,12 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t pop_heap(R&& r, Comp comp = {}, Proj proj = {}); @@ -2445,12 +2543,12 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I make_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t make_heap(R&& r, Comp comp = {}, Proj proj = {}); @@ -2463,12 +2561,12 @@ Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr I sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> + template requires Sortable, Comp, Proj> constexpr safe_iterator_t sort_heap(R&& r, Comp comp = {}, Proj proj = {}); @@ -2489,10 +2587,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); } @@ -2515,10 +2613,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr safe_iterator_t is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); } @@ -2534,13 +2632,13 @@ namespace ranges { template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr T min(initializer_list r, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> requires IndirectlyCopyableStorable, iter_value_t>*> constexpr iter_value_t> min(R&& r, Comp comp = {}, Proj proj = {}); @@ -2556,13 +2654,13 @@ namespace ranges { template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr T max(initializer_list r, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> requires IndirectlyCopyableStorable, iter_value_t>*> constexpr iter_value_t> max(R&& r, Comp comp = {}, Proj proj = {}); @@ -2579,20 +2677,32 @@ namespace ranges { template struct minmax_result { - T min; - T max; + [[no_unique_address]] T min; + [[no_unique_address]] T max; + + template + requires ConvertibleTo + operator minmax_result() const & { + return {min, max}; + } + + template + requires ConvertibleTo + operator minmax_result() && { + return {std::move(min), std::move(max)}; + } }; template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr minmax_result minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); template> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr minmax_result minmax(initializer_list r, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> requires IndirectlyCopyableStorable, iter_value_t>*> constexpr minmax_result>> minmax(R&& r, Comp comp = {}, Proj proj = {}); @@ -2613,10 +2723,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr safe_iterator_t min_element(R&& r, Comp comp = {}, Proj proj = {}); } @@ -2636,10 +2746,10 @@ namespace ranges { template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> + IndirectStrictWeakOrder> Comp = ranges::less> constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> constexpr safe_iterator_t max_element(R&& r, Comp comp = {}, Proj proj = {}); } @@ -2660,13 +2770,16 @@ ForwardIterator first, ForwardIterator last, Compare comp); namespace ranges { + template + using minmax_element_result = minmax_result; + template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr minmax_result + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr minmax_element_result minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); template, Proj>> Comp = ranges::less<>> - constexpr minmax_result> + IndirectStrictWeakOrder, Proj>> Comp = ranges::less> + constexpr minmax_element_result> minmax_element(R&& r, Comp comp = {}, Proj proj = {}); } @@ -2703,14 +2816,14 @@ template S1, InputIterator I2, Sentinel S2, class Proj1 = identity, class Proj2 = identity, IndirectStrictWeakOrder, projected> Comp = - ranges::less<>> + ranges::less> constexpr bool lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template, Proj1>, - projected, Proj2>> Comp = ranges::less<>> + projected, Proj2>> Comp = ranges::less> constexpr bool lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); @@ -2739,12 +2852,12 @@ BidirectionalIterator last, Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr bool next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); - template, + template requires Sortable, Comp, Proj> constexpr bool @@ -2759,12 +2872,12 @@ BidirectionalIterator last, Compare comp); namespace ranges { - template S, class Comp = ranges::less<>, + template S, class Comp = ranges::less, class Proj = identity> requires Sortable constexpr bool prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); - template, + template requires Sortable, Comp, Proj> constexpr bool @@ -2775,7 +2888,7 @@ \rSec1[alg.nonmodifying]{Non-modifying sequence operations} -\rSec2[alg.all_of]{All of} +\rSec2[alg.all.of]{All of} \indexlibrary{\idxcode{all_of}}% \begin{itemdecl} @@ -2785,14 +2898,12 @@ bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr bool all_of(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr bool all_of(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -2811,7 +2922,7 @@ At most \tcode{last - first} applications of the predicate and any projection. \end{itemdescr} -\rSec2[alg.any_of]{Any of} +\rSec2[alg.any.of]{Any of} \indexlibrary{\idxcode{any_of}}% \begin{itemdecl} @@ -2821,14 +2932,12 @@ bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr bool any_of(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr bool any_of(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -2846,7 +2955,7 @@ and any projection. \end{itemdescr} -\rSec2[alg.none_of]{None of} +\rSec2[alg.none.of]{None of} \indexlibrary{\idxcode{none_of}}% \begin{itemdecl} @@ -2856,14 +2965,12 @@ bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr bool none_of(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr bool none_of(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -2965,16 +3072,14 @@ \indexlibrary{\idxcode{for_each}}% \begin{itemdecl} -namespace ranges { - template S, class Proj = identity, - IndirectUnaryInvocable> Fun> - constexpr for_each_result - for_each(I first, S last, Fun f, Proj proj = {}); - template, Proj>> Fun> - constexpr for_each_result, Fun> - for_each(R&& r, Fun f, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryInvocable> Fun> + constexpr ranges::for_each_result + ranges::for_each(I first, S last, Fun f, Proj proj = {}); +template, Proj>> Fun> + constexpr ranges::for_each_result, Fun> + ranges::for_each(R&& r, Fun f, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3109,29 +3214,27 @@ ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> - constexpr I find(I first, S last, const T& value, Proj proj = {}); - template - requires IndirectRelation, projected, Proj>, const T*> - constexpr safe_iterator_t - find(R&& r, const T& value, Proj proj = {}); - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr safe_iterator_t - find_if(R&& r, Pred pred, Proj proj = {}); - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr safe_iterator_t - find_if_not(R&& r, Pred pred, Proj proj = {}); -} +template S, class T, class Proj = identity> + requires IndirectRelation, const T*> + constexpr I ranges::find(I first, S last, const T& value, Proj proj = {}); +template + requires IndirectRelation, Proj>, const T*> + constexpr safe_iterator_t + ranges::find(R&& r, const T& value, Proj proj = {}); +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr I ranges::find_if(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr safe_iterator_t + ranges::find_if(R&& r, Pred pred, Proj proj = {}); +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr I ranges::find_if_not(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr safe_iterator_t + ranges::find_if_not(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3186,20 +3289,18 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); -namespace ranges { - template S1, ForwardIterator I2, Sentinel S2, - class Pred = ranges::equal_to<>, class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable - constexpr subrange - find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> - constexpr safe_subrange_t - find_end(R1&& r1, R2&& r2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, ForwardIterator I2, Sentinel S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires IndirectlyComparable + constexpr subrange + ranges::find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> + constexpr safe_subrange_t + ranges::find_end(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3273,23 +3374,21 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); -namespace ranges { - template S1, ForwardIterator I2, Sentinel S2, - class Proj1 = identity, class Proj2 = identity, - IndirectRelation, - projected> Pred = ranges::equal_to<>> - constexpr I1 find_first_of(I1 first1, S1 last1, I2 first2, S2 last2, - Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, Proj1>, - projected, Proj2>> Pred = ranges::equal_to<>> - constexpr safe_iterator_t - find_first_of(R1&& r1, R2&& r2, - Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, ForwardIterator I2, Sentinel S2, + class Proj1 = identity, class Proj2 = identity, + IndirectRelation, + projected> Pred = ranges::equal_to> + constexpr I1 ranges::find_first_of(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template, Proj1>, + projected, Proj2>> Pred = ranges::equal_to> + constexpr safe_iterator_t + ranges::find_first_of(R1&& r1, R2&& r2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3342,16 +3441,12 @@ ForwardIterator first, ForwardIterator last, BinaryPredicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectRelation> Pred = ranges::equal_to<>> - constexpr I adjacent_find(I first, S last, Pred pred = {}, - Proj proj = {}); - template, Proj>> Pred = ranges::equal_to<>> - constexpr safe_iterator_t - adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectRelation> Pred = ranges::equal_to> + constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); +template, Proj>> Pred = ranges::equal_to> + constexpr safe_iterator_t ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3403,24 +3498,22 @@ count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> - constexpr iter_difference_t - count(I first, S last, const T& value, Proj proj = {}); - template - requires IndirectRelation, projected, Proj>, const T*> - constexpr iter_difference_t> - count(R&& r, const T& value, Proj proj = {}); - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr iter_difference_t - count_if(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr iter_difference_t> - count_if(R&& r, Pred pred, Proj proj = {}); -} +template S, class T, class Proj = identity> + requires IndirectRelation, const T*> + constexpr iter_difference_t + ranges::count(I first, S last, const T& value, Proj proj = {}); +template + requires IndirectRelation, Proj>, const T*> + constexpr iter_difference_t> + ranges::count(R&& r, const T& value, Proj proj = {}); +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr iter_difference_t + ranges::count_if(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr iter_difference_t> + ranges::count_if(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3502,22 +3595,20 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - class Proj1 = identity, class Proj2 = identity, - IndirectRelation, - projected> Pred = ranges::equal_to<>> - constexpr mismatch_result - mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, Proj1>, - projected, Proj2>> Pred = ranges::equal_to<>> - constexpr mismatch_result, safe_iterator_t> - mismatch(R1&& r1, R2&& r2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + class Proj1 = identity, class Proj2 = identity, + IndirectRelation, + projected> Pred = ranges::equal_to> + constexpr ranges::mismatch_result + ranges::mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template, Proj1>, + projected, Proj2>> Pred = ranges::equal_to> + constexpr ranges::mismatch_result, safe_iterator_t> + ranges::mismatch(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3541,17 +3632,18 @@ for the overloads with both parameters \tcode{pred} and \tcode{proj1}. \end{itemize} +\pnum +Let $N$ be $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$. + \pnum \returns \tcode{\{ first1 + n, first2 + n \}}, -where \tcode{n} is the smallest integer such that $E$ holds, -or $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ -if no such integer exists. +where \tcode{n} is the smallest integer in \range{0}{$N$} such that $E$ holds, +or $N$ if no such integer exists. \pnum \complexity -At most $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ -applications of the corresponding predicate and any projections. +At most $N$ applications of the corresponding predicate and any projections. \end{itemdescr} \rSec2[alg.equal]{Equal} @@ -3596,19 +3688,17 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - class Pred = ranges::equal_to<>, class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable - constexpr bool equal(I1 first1, S1 last1, I2 first2, S2 last2, - Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, - class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> - constexpr bool equal(R1&& r1, R2&& r2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires IndirectlyComparable + constexpr bool ranges::equal(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::equal(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3668,7 +3758,7 @@ \end{itemize} \end{itemdescr} -\rSec2[alg.is_permutation]{Is permutation} +\rSec2[alg.is.permutation]{Is permutation} \indexlibrary{\idxcode{is_permutation}}% \begin{itemdecl} @@ -3729,20 +3819,18 @@ \indexlibrary{\idxcode{is_permutation}}% \begin{itemdecl} -namespace ranges { - template S1, ForwardIterator I2, - Sentinel S2, class Pred = ranges::equal_to<>, class Proj1 = identity, - class Proj2 = identity> - requires IndirectlyComparable - constexpr bool is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, - Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, - class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> - constexpr bool is_permutation(R1&& r1, R2&& r2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, ForwardIterator I2, + Sentinel S2, class Pred = ranges::equal_to, class Proj1 = identity, + class Proj2 = identity> + requires IndirectlyComparable + constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3819,21 +3907,19 @@ \indexlibrary{\idxcode{search}}% \begin{itemdecl} -namespace ranges { - template S1, ForwardIterator I2, - Sentinel S2, class Pred = ranges::equal_to<>, - class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable - constexpr subrange - search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, - class Proj1 = identity, class Proj2 = identity> - requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> - constexpr safe_subrange_t - search(R1&& r1, R2&& r2, Pred pred = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, ForwardIterator I2, + Sentinel S2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires IndirectlyComparable + constexpr subrange + ranges::search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> + constexpr safe_subrange_t + ranges::search(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -3909,20 +3995,18 @@ \indexlibrary{\idxcode{search_n}}% \begin{itemdecl} -namespace ranges { - template S, class T, - class Pred = ranges::equal_to<>, class Proj = identity> - requires IndirectlyComparable - constexpr subrange - search_n(I first, S last, iter_difference_t count, - const T& value, Pred pred = {}, Proj proj = {}); - template, - class Proj = identity> - requires IndirectlyComparable, const T*, Pred, Proj> - constexpr safe_subrange_t - search_n(R&& r, iter_difference_t> count, - const T& value, Pred pred = {}, Proj proj = {}); -} +template S, class T, + class Pred = ranges::equal_to, class Proj = identity> + requires IndirectlyComparable + constexpr subrange + ranges::search_n(I first, S last, iter_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); +template + requires IndirectlyComparable, const T*, Pred, Proj> + constexpr safe_subrange_t + ranges::search_n(R&& r, iter_difference_t> count, + const T& value, Pred pred = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3968,16 +4052,12 @@ constexpr OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); -namespace ranges { - template S, WeaklyIncrementable O> - requires IndirectlyCopyable - constexpr copy_result - copy(I first, S last, O result); - template - requires IndirectlyCopyable, O> - constexpr copy_result, O> - copy(R&& r, O result); -} +template S, WeaklyIncrementable O> + requires IndirectlyCopyable + constexpr ranges::copy_result ranges::copy(I first, S last, O result); +template + requires IndirectlyCopyable, O> + constexpr ranges::copy_result, O> ranges::copy(R&& r, O result); \end{itemdecl} \begin{itemdescr} @@ -4050,12 +4130,10 @@ ForwardIterator1 first, Size n, ForwardIterator2 result); -namespace ranges { - template - requires IndirectlyCopyable - constexpr copy_n_result - copy_n(I first, iter_difference_t n, O result); -} +template + requires IndirectlyCopyable + constexpr ranges::copy_n_result + ranges::copy_n(I first, iter_difference_t n, O result); \end{itemdecl} \begin{itemdescr} @@ -4094,18 +4172,16 @@ ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); -namespace ranges { - template S, WeaklyIncrementable O, class Proj = identity, - IndirectUnaryPredicate> Pred> - requires IndirectlyCopyable - constexpr copy_if_result - copy_if(I first, S last, O result, Pred pred, Proj proj = {}); - template, Proj>> Pred> - requires IndirectlyCopyable, O> - constexpr copy_if_result, O> - copy_if(R&& r, O result, Pred pred, Proj proj = {}); -} +template S, WeaklyIncrementable O, class Proj = identity, + IndirectUnaryPredicate> Pred> + requires IndirectlyCopyable + constexpr ranges::copy_if_result + ranges::copy_if(I first, S last, O result, Pred pred, Proj proj = {}); +template, Proj>> Pred> + requires IndirectlyCopyable, O> + constexpr ranges::copy_if_result, O> + ranges::copy_if(R&& r, O result, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4168,16 +4244,14 @@ BidirectionalIterator1 last, BidirectionalIterator2 result); -namespace ranges { - template S1, BidirectionalIterator I2> - requires IndirectlyCopyable - constexpr copy_backward_result - copy_backward(I1 first, S1 last, I2 result); - template - requires IndirectlyCopyable, I> - constexpr copy_backward_result, I> - copy_backward(R&& r, I result); -} +template S1, BidirectionalIterator I2> + requires IndirectlyCopyable + constexpr ranges::copy_backward_result + ranges::copy_backward(I1 first, S1 last, I2 result); +template + requires IndirectlyCopyable, I> + constexpr ranges::copy_backward_result, I> + ranges::copy_backward(R&& r, I result); \end{itemdecl} \begin{itemdescr} @@ -4222,16 +4296,14 @@ constexpr OutputIterator move(InputIterator first, InputIterator last, OutputIterator result); -namespace ranges { - template S, WeaklyIncrementable O> - requires IndirectlyMovable - constexpr move_result - move(I first, S last, O result); - template - requires IndirectlyMovable, O> - constexpr move_result, O> - move(R&& r, O result); -} +template S, WeaklyIncrementable O> + requires IndirectlyMovable + constexpr ranges::move_result + ranges::move(I first, S last, O result); +template + requires IndirectlyMovable, O> + constexpr ranges::move_result, O> + ranges::move(R&& r, O result); \end{itemdecl} \begin{itemdescr} @@ -4314,16 +4386,14 @@ move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); -namespace ranges { - template S1, BidirectionalIterator I2> - requires IndirectlyMovable - constexpr move_backward_result - move_backward(I1 first, S1 last, I2 result); - template - requires IndirectlyMovable, I> - constexpr move_backward_result, I> - move_backward(R&& r, I result); -} +template S1, BidirectionalIterator I2> + requires IndirectlyMovable + constexpr ranges::move_backward_result + ranges::move_backward(I1 first, S1 last, I2 result); +template + requires IndirectlyMovable, I> + constexpr ranges::move_backward_result, I> + ranges::move_backward(R&& r, I result); \end{itemdecl} \begin{itemdescr} @@ -4383,16 +4453,14 @@ ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); -namespace ranges { - template S1, InputIterator I2, Sentinel S2> - requires IndirectlySwappable - constexpr swap_ranges_result - swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); - template - requires IndirectlySwappable, iterator_t> - constexpr swap_ranges_result, safe_iterator_t> - swap_ranges(R1&& r1, R2&& r2); -} +template S1, InputIterator I2, Sentinel S2> + requires IndirectlySwappable + constexpr ranges::swap_ranges_result + ranges::swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); +template + requires IndirectlySwappable, iterator_t> + constexpr ranges::swap_ranges_result, safe_iterator_t> + ranges::swap_ranges(R1&& r1, R2&& r2); \end{itemdecl} \begin{itemdescr} @@ -4488,33 +4556,31 @@ ForwardIterator2 first2, ForwardIterator result, BinaryOperation binary_op); -namespace ranges { - template S, WeaklyIncrementable O, - CopyConstructible F, class Proj = identity> - requires Writable>> - constexpr unary_transform_result - transform(I first1, S last1, O result, F op, Proj proj = {}); - template - requires Writable, Proj>>> - constexpr unary_transform_result, O> - transform(R&& r, O result, F op, Proj proj = {}); - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, CopyConstructible F, class Proj1 = identity, - class Proj2 = identity> - requires Writable, - projected>> - constexpr binary_transform_result - transform(I1 first1, S1 last1, I2 first2, S2 last2, O result, - F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); - template - requires Writable, Proj1>, - projected, Proj2>>> - constexpr binary_transform_result, safe_iterator_t, O> - transform(R1&& r1, R2&& r2, O result, - F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S, WeaklyIncrementable O, + CopyConstructible F, class Proj = identity> + requires Writable>> + constexpr ranges::unary_transform_result + ranges::transform(I first1, S last1, O result, F op, Proj proj = {}); +template + requires Writable, Proj>>> + constexpr ranges::unary_transform_result, O> + ranges::transform(R&& r, O result, F op, Proj proj = {}); +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, CopyConstructible F, class Proj1 = identity, + class Proj2 = identity> + requires Writable, + projected>> + constexpr ranges::binary_transform_result + ranges::transform(I1 first1, S1 last1, I2 first2, S2 last2, O result, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires Writable, Proj1>, + projected, Proj2>>> + constexpr ranges::binary_transform_result, safe_iterator_t, O> + ranges::transform(R1&& r1, R2&& r2, O result, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -4549,7 +4615,7 @@ \pnum \requires -\tcode{op} and \tcode{binary_op} shall not invalidate iterators or subranges, or +\tcode{op} and \tcode{binary_op} shall not invalidate iterators or subranges, nor modify elements in the ranges \begin{itemize} \item \crange{first1}{first1 + $N$}, @@ -4609,27 +4675,25 @@ ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); -namespace ranges { - template S, class T1, class T2, class Proj = identity> - requires Writable && - IndirectRelation, projected, const T1*> - constexpr I - replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); - template - requires Writable, const T2&> && - IndirectRelation, projected, Proj>, const T1*> - constexpr safe_iterator_t - replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); - template S, class T, class Proj = identity, - IndirectUnaryPredicate> Pred> - requires Writable - constexpr I replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); - template, Proj>> Pred> - requires Writable, const T&> - constexpr safe_iterator_t - replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); -} +template S, class T1, class T2, class Proj = identity> + requires Writable && + IndirectRelation, const T1*> + constexpr I + ranges::replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); +template + requires Writable, const T2&> && + IndirectRelation, Proj>, const T1*> + constexpr safe_iterator_t + ranges::replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); +template S, class T, class Proj = identity, + IndirectUnaryPredicate> Pred> + requires Writable + constexpr I ranges::replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); +template, Proj>> Pred> + requires Writable, const T&> + constexpr safe_iterator_t + ranges::replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4690,35 +4754,33 @@ ForwardIterator2 result, Predicate pred, const T& new_value); -namespace ranges { - template S, class T1, class T2, OutputIterator O, - class Proj = identity> - requires IndirectlyCopyable && - IndirectRelation, projected, const T1*> - constexpr replace_copy_result - replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, - Proj proj = {}); - template O, - class Proj = identity> - requires IndirectlyCopyable, O> && - IndirectRelation, projected, Proj>, const T1*> - constexpr replace_copy_result, O> - replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, - Proj proj = {}); - - template S, class T, OutputIterator O, - class Proj = identity, IndirectUnaryPredicate> Pred> - requires IndirectlyCopyable - constexpr replace_copy_if_result - replace_copy_if(I first, S last, O result, Pred pred, const T& new_value, - Proj proj = {}); - template O, class Proj = identity, - IndirectUnaryPredicate, Proj>> Pred> - requires IndirectlyCopyable, O> - constexpr replace_copy_if_result, O> - replace_copy_if(R&& r, O result, Pred pred, const T& new_value, - Proj proj = {}); -} +template S, class T1, class T2, OutputIterator O, + class Proj = identity> + requires IndirectlyCopyable && + IndirectRelation, const T1*> + constexpr ranges::replace_copy_result + ranges::replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, + Proj proj = {}); +template O, + class Proj = identity> + requires IndirectlyCopyable, O> && + IndirectRelation, Proj>, const T1*> + constexpr ranges::replace_copy_result, O> + ranges::replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, + Proj proj = {}); + +template S, class T, OutputIterator O, + class Proj = identity, IndirectUnaryPredicate> Pred> + requires IndirectlyCopyable + constexpr ranges::replace_copy_if_result + ranges::replace_copy_if(I first, S last, O result, Pred pred, const T& new_value, + Proj proj = {}); +template O, class Proj = identity, + IndirectUnaryPredicate, Proj>> Pred> + requires IndirectlyCopyable, O> + constexpr ranges::replace_copy_if_result, O> + ranges::replace_copy_if(R&& r, O result, Pred pred, const T& new_value, + Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4786,14 +4848,12 @@ ForwardIterator first, Size n, const T& value); -namespace ranges { - template O, Sentinel S> - constexpr O fill(O first, S last, const T& value); - template R> - constexpr safe_iterator_t fill(R&& r, const T& value); - template O> - constexpr O fill_n(O first, iter_difference_t n, const T& value); -} +template O, Sentinel S> + constexpr O ranges::fill(O first, S last, const T& value); +template R> + constexpr safe_iterator_t ranges::fill(R&& r, const T& value); +template O> + constexpr O ranges::fill_n(O first, iter_difference_t n, const T& value); \end{itemdecl} \begin{itemdescr} @@ -4841,17 +4901,15 @@ ForwardIterator generate_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Generator gen); -namespace ranges { - template S, CopyConstructible F> - requires Invocable && Writable> - constexpr O generate(O first, S last, F gen); - template - requires Invocable && OutputRange> - constexpr safe_iterator_t generate(R&& r, F gen); - template - requires Invocable && Writable> - constexpr O generate_n(O first, iter_difference_t n, F gen); -} +template S, CopyConstructible F> + requires Invocable && Writable> + constexpr O ranges::generate(O first, S last, F gen); +template + requires Invocable && OutputRange> + constexpr safe_iterator_t ranges::generate(R&& r, F gen); +template + requires Invocable && Writable> + constexpr O ranges::generate_n(O first, iter_difference_t n, F gen); \end{itemdecl} \begin{itemdescr} @@ -4899,24 +4957,22 @@ ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class T, class Proj = identity> - requires IndirectRelation, projected, const T*> - constexpr I remove(I first, S last, const T& value, Proj proj = {}); - template - requires Permutable> && - IndirectRelation, projected, Proj>, const T*> - constexpr safe_iterator_t - remove(R&& r, const T& value, Proj proj = {}); - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr I remove_if(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - requires Permutable> - constexpr safe_iterator_t - remove_if(R&& r, Pred pred, Proj proj = {}); -} +template S, class T, class Proj = identity> + requires IndirectRelation, const T*> + constexpr I ranges::remove(I first, S last, const T& value, Proj proj = {}); +template + requires Permutable> && + IndirectRelation, Proj>, const T*> + constexpr safe_iterator_t + ranges::remove(R&& r, const T& value, Proj proj = {}); +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr I ranges::remove_if(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + requires Permutable> + constexpr safe_iterator_t + ranges::remove_if(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4988,29 +5044,27 @@ ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); -namespace ranges { - template S, WeaklyIncrementable O, class T, - class Proj = identity> - requires IndirectlyCopyable && - IndirectRelation, projected, const T*> - constexpr remove_copy_result - remove_copy(I first, S last, O result, const T& value, Proj proj = {}); - template - requires IndirectlyCopyable, O> && - IndirectRelation, projected, Proj>, const T*> - constexpr remove_copy_result, O> - remove_copy(R&& r, O result, const T& value, Proj proj = {}); - template S, WeaklyIncrementable O, - class Proj = identity, IndirectUnaryPredicate> Pred> - requires IndirectlyCopyable - constexpr remove_copy_if_result - remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); - template, Proj>> Pred> - requires IndirectlyCopyable, O> - constexpr remove_copy_if_result, O> - remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); -} +template S, WeaklyIncrementable O, class T, + class Proj = identity> + requires IndirectlyCopyable && + IndirectRelation, const T*> + constexpr ranges::remove_copy_result + ranges::remove_copy(I first, S last, O result, const T& value, Proj proj = {}); +template + requires IndirectlyCopyable, O> && + IndirectRelation, Proj>, const T*> + constexpr ranges::remove_copy_result, O> + ranges::remove_copy(R&& r, O result, const T& value, Proj proj = {}); +template S, WeaklyIncrementable O, + class Proj = identity, IndirectUnaryPredicate> Pred> + requires IndirectlyCopyable + constexpr ranges::remove_copy_if_result + ranges::remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); +template, Proj>> Pred> + requires IndirectlyCopyable, O> + constexpr ranges::remove_copy_if_result, O> + ranges::remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5078,16 +5132,14 @@ ForwardIterator first, ForwardIterator last, BinaryPredicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectRelation> C = ranges::equal_to<>> - constexpr I unique(I first, S last, C comp = {}, Proj proj = {}); - template, Proj>> C = ranges::equal_to<>> - requires Permutable> - constexpr safe_iterator_t - unique(R&& r, C comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectRelation> C = ranges::equal_to<>> + constexpr I ranges::unique(I first, S last, C comp = {}, Proj proj = {}); +template, Proj>> C = ranges::equal_to> + requires Permutable> + constexpr safe_iterator_t + ranges::unique(R&& r, C comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5154,24 +5206,22 @@ ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); -namespace ranges { - template S, WeaklyIncrementable O, - class Proj = identity, IndirectRelation> C = ranges::equal_to<>> - requires IndirectlyCopyable && - (ForwardIterator || - (InputIterator && Same, iter_value_t>) || - IndirectlyCopyableStorable) - constexpr unique_copy_result - unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); - template, Proj>> C = ranges::equal_to<>> - requires IndirectlyCopyable, O> && - (ForwardIterator> || - (InputIterator && Same>, iter_value_t>) || - IndirectlyCopyableStorable, O>) - constexpr unique_copy_result, O> - unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); -} +template S, WeaklyIncrementable O, + class Proj = identity, IndirectRelation> C = ranges::equal_to> + requires IndirectlyCopyable && + (ForwardIterator || + (InputIterator && Same, iter_value_t>) || + IndirectlyCopyableStorable) + constexpr ranges::unique_copy_result + ranges::unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); +template, Proj>> C = ranges::equal_to> + requires IndirectlyCopyable, O> && + (ForwardIterator> || + (InputIterator && Same>, iter_value_t>) || + IndirectlyCopyableStorable, O>) + constexpr ranges::unique_copy_result, O> + ranges::unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5255,14 +5305,12 @@ void reverse(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last); -namespace ranges { - template S> - requires Permutable - constexpr I reverse(I first, S last); - template - requires Permutable> - constexpr safe_iterator_t reverse(R&& r); -} +template S> + requires Permutable + constexpr I ranges::reverse(I first, S last); +template + requires Permutable> + constexpr safe_iterator_t ranges::reverse(R&& r); \end{itemdecl} \begin{itemdescr} @@ -5300,16 +5348,14 @@ BidirectionalIterator first, BidirectionalIterator last, ForwardIterator result); -namespace ranges { - template S, WeaklyIncrementable O> - requires IndirectlyCopyable - constexpr reverse_copy_result - reverse_copy(I first, S last, O result); - template - requires IndirectlyCopyable, O> - constexpr reverse_copy_result, O> - reverse_copy(R&& r, O result); -} +template S, WeaklyIncrementable O> + requires IndirectlyCopyable + constexpr ranges::reverse_copy_result + ranges::reverse_copy(I first, S last, O result); +template + requires IndirectlyCopyable, O> + constexpr ranges::reverse_copy_result, O> + ranges::reverse_copy(R&& r, O result); \end{itemdecl} \begin{itemdescr} @@ -5354,10 +5400,8 @@ rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last); -namespace ranges { - template S> - constexpr subrange rotate(I first, I middle, S last); -} +template S> + constexpr subrange ranges::rotate(I first, I middle, S last); \end{itemdecl} \begin{itemdescr} @@ -5397,11 +5441,9 @@ \end{itemdescr} \begin{itemdecl} -namespace ranges { - template - requires Permutable> - constexpr safe_subrange_t rotate(R&& r, iterator_t middle); -} +template + requires Permutable> + constexpr safe_subrange_t ranges::rotate(R&& r, iterator_t middle); \end{itemdecl} \begin{itemdescr} @@ -5423,12 +5465,10 @@ ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result); -namespace ranges { template S, WeaklyIncrementable O> requires IndirectlyCopyable - constexpr rotate_copy_result - rotate_copy(I first, I middle, S last, O result); -} + constexpr ranges::rotate_copy_result + ranges::rotate_copy(I first, I middle, S last, O result); \end{itemdecl} \begin{itemdescr} @@ -5463,12 +5503,10 @@ \end{itemdescr} \begin{itemdecl} -namespace ranges { - template - requires IndirectlyCopyable, O> - constexpr rotate_copy_result, O> - rotate_copy(R&& r, iterator_t middle, O result); -} +template + requires IndirectlyCopyable, O> + constexpr ranges::rotate_copy_result, O> + ranges::rotate_copy(R&& r, iterator_t middle, O result); \end{itemdecl} \begin{itemdescr} @@ -5559,16 +5597,14 @@ RandomAccessIterator last, UniformRandomBitGenerator&& g); -namespace ranges { - template S, class Gen> - requires Permutable && - UniformRandomBitGenerator> - I shuffle(I first, S last, Gen&& g); - template - requires Permutable> && - UniformRandomBitGenerator> - safe_iterator_t shuffle(R&& r, Gen&& g); -} +template S, class Gen> + requires Permutable && + UniformRandomBitGenerator> + I ranges::shuffle(I first, S last, Gen&& g); +template + requires Permutable> && + UniformRandomBitGenerator> + safe_iterator_t ranges::shuffle(R&& r, Gen&& g); \end{itemdecl} \begin{itemdescr} @@ -5792,17 +5828,15 @@ RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - sort(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - sort(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::sort(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::sort(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5853,16 +5887,14 @@ RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - I stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - safe_iterator_t - stable_sort(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + I ranges::stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + safe_iterator_t + ranges::stable_sort(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5927,13 +5959,11 @@ RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -5973,12 +6003,10 @@ \end{itemdescr} \begin{itemdecl} -namespace ranges { - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - partial_sort(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); -} +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::partial_sort(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6022,24 +6050,22 @@ RandomAccessIterator result_last, Compare comp); -namespace ranges { - template S1, RandomAccessIterator I2, Sentinel S2, - class Comp = ranges::less<>, class Proj1 = identity, class Proj2 = identity> - requires IndirectlyCopyable && Sortable && - IndirectStrictWeakOrder, projected> - constexpr I2 - partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, - class Proj1 = identity, class Proj2 = identity> - requires IndirectlyCopyable, iterator_t> && - Sortable, Comp, Proj2> && - IndirectStrictWeakOrder, Proj1>, - projected, Proj2>> - constexpr safe_iterator_t - partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, RandomAccessIterator I2, Sentinel S2, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires IndirectlyCopyable && Sortable && + IndirectStrictWeakOrder, projected> + constexpr I2 + ranges::partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires IndirectlyCopyable, iterator_t> && + Sortable, Comp, Proj2> && + IndirectStrictWeakOrder, Proj1>, + projected, Proj2>> + constexpr safe_iterator_t + ranges::partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -6156,14 +6182,12 @@ \indexlibrary{\idxcode{is_sorted}}% \begin{itemdecl} -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr bool is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr bool is_sorted(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr bool ranges::is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr bool ranges::is_sorted(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6193,15 +6217,13 @@ ForwardIterator first, ForwardIterator last, Compare comp); -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr safe_iterator_t - is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr safe_iterator_t + ranges::is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6241,13 +6263,11 @@ RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6289,12 +6309,10 @@ \end{itemdescr} \begin{itemdecl} -namespace ranges { - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); -} +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6334,17 +6352,15 @@ lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); -namespace ranges { - template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I lower_bound(I first, S last, const T& value, Comp comp = {}, - Proj proj = {}); - template, Proj>> Comp = - ranges::less<>> - constexpr safe_iterator_t - lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); -} +template S, class T, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::lower_bound(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); +template, Proj>> Comp = + ranges::less> + constexpr safe_iterator_t + ranges::lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6384,16 +6400,14 @@ upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); -namespace ranges { - template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = - ranges::less<>> - constexpr safe_iterator_t - upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); -} +template S, class T, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = + ranges::less> + constexpr safe_iterator_t + ranges::upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6434,17 +6448,15 @@ ForwardIterator last, const T& value, Compare comp); -namespace ranges { - template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr subrange - equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = - ranges::less<>> - constexpr safe_subrange_t - equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); -} +template S, class T, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr subrange + ranges::equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = + ranges::less> + constexpr safe_subrange_t + ranges::equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6498,17 +6510,15 @@ binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); -namespace ranges { - template S, class T, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr bool binary_search(I first, S last, const T& value, Comp comp = {}, - Proj proj = {}); - template, Proj>> Comp = - ranges::less<>> - constexpr bool binary_search(R&& r, const T& value, Comp comp = {}, - Proj proj = {}); -} +template S, class T, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr bool ranges::binary_search(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); +template, Proj>> Comp = + ranges::less> + constexpr bool ranges::binary_search(R&& r, const T& value, Comp comp = {}, + Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6550,14 +6560,12 @@ bool is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr bool is_partitioned(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr bool is_partitioned(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr bool ranges::is_partitioned(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr bool ranges::is_partitioned(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6587,17 +6595,15 @@ partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr I - partition(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - requires Permutable> - constexpr safe_iterator_t - partition(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr I + ranges::partition(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + requires Permutable> + constexpr safe_iterator_t + ranges::partition(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6652,16 +6658,14 @@ stable_partition(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - requires Permutable - I stable_partition(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - requires Permutable> - safe_iterator_t stable_partition(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + requires Permutable + I ranges::stable_partition(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + requires Permutable> + safe_iterator_t ranges::stable_partition(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6720,21 +6724,19 @@ ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); -namespace ranges { - template S, WeaklyIncrementable O1, WeaklyIncrementable O2, - class Proj = identity, IndirectUnaryPredicate> Pred> - requires IndirectlyCopyable && IndirectlyCopyable - constexpr partition_copy_result - partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, - Proj proj = {}); - template, Proj>> Pred> - requires IndirectlyCopyable, O1> && - IndirectlyCopyable, O2> - constexpr partition_copy_result, O1, O2> - partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); -} +template S, WeaklyIncrementable O1, WeaklyIncrementable O2, + class Proj = identity, IndirectUnaryPredicate> Pred> + requires IndirectlyCopyable && IndirectlyCopyable + constexpr ranges::partition_copy_result + ranges::partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, + Proj proj = {}); +template, Proj>> Pred> + requires IndirectlyCopyable, O1> && + IndirectlyCopyable, O2> + constexpr ranges::partition_copy_result, O1, O2> + ranges::partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6784,15 +6786,13 @@ constexpr ForwardIterator partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); -namespace ranges { - template S, class Proj = identity, - IndirectUnaryPredicate> Pred> - constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); - template, Proj>> Pred> - constexpr safe_iterator_t - partition_point(R&& r, Pred pred, Proj proj = {}); -} +template S, class Proj = identity, + IndirectUnaryPredicate> Pred> + constexpr I ranges::partition_point(I first, S last, Pred pred, Proj proj = {}); +template, Proj>> Pred> + constexpr safe_iterator_t + ranges::partition_point(R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6851,21 +6851,19 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, class Proj1 = identity, - class Proj2 = identity> - requires Mergeable - constexpr merge_result - merge(I1 first1, S1 last1, I2 first2, S2 last2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, - class Proj1 = identity, class Proj2 = identity> - requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> - constexpr merge_result, safe_iterator_t, O> - merge(R1&& r1, R2&& r2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, class Comp = ranges::less, class Proj1 = identity, + class Proj2 = identity> + requires Mergeable + constexpr ranges::merge_result + ranges::merge(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::merge_result, safe_iterator_t, O> + ranges::merge(R1&& r1, R2&& r2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -6944,12 +6942,10 @@ BidirectionalIterator middle, BidirectionalIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + I ranges::inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6998,12 +6994,10 @@ \end{itemdescr} \begin{itemdecl} -namespace ranges { - template, class Proj = identity> - requires Sortable, Comp, Proj> - safe_iterator_t - inplace_merge(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); -} +template + requires Sortable, Comp, Proj> + safe_iterator_t + ranges::inplace_merge(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7048,20 +7042,18 @@ ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - class Proj1 = identity, class Proj2 = identity, - IndirectStrictWeakOrder, - projected> Comp = ranges::less<>> - constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, Proj1>, - projected, Proj2>> Comp = ranges::less<>> - constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + class Proj1 = identity, class Proj2 = identity, + IndirectStrictWeakOrder, + projected> Comp = ranges::less> + constexpr bool ranges::includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template, Proj1>, + projected, Proj2>> Comp = ranges::less> + constexpr bool ranges::includes(R1&& r1, R2&& r2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7124,21 +7116,19 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, - class Proj1 = identity, class Proj2 = identity> - requires Mergeable - constexpr set_union_result - set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); - template, class Proj1 = identity, class Proj2 = identity> - requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> - constexpr set_union_result, safe_iterator_t, O> - set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires Mergeable + constexpr ranges::set_union_result + ranges::set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::set_union_result, safe_iterator_t, O> + ranges::set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7221,21 +7211,19 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, - class Proj1 = identity, class Proj2 = identity> - requires Mergeable - constexpr set_intersection_result - set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, class Proj1 = identity, class Proj2 = identity> - requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> - constexpr set_intersection_result, safe_iterator_t, O> - set_intersection(R1&& r1, R2&& r2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires Mergeable + constexpr ranges::set_intersection_result + ranges::set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::set_intersection_result, safe_iterator_t, O> + ranges::set_intersection(R1&& r1, R2&& r2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7316,21 +7304,19 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, - class Proj1 = identity, class Proj2 = identity> - requires Mergeable - constexpr set_difference_result - set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, class Proj1 = identity, class Proj2 = identity> - requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> - constexpr set_difference_result, O> - set_difference(R1&& r1, R2&& r2, O result, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires Mergeable + constexpr ranges::set_difference_result + ranges::set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template + requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::set_difference_result, O> + ranges::set_difference(R1&& r1, R2&& r2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7412,22 +7398,20 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - WeaklyIncrementable O, class Comp = ranges::less<>, - class Proj1 = identity, class Proj2 = identity> - requires Mergeable - constexpr set_symmetric_difference_result - set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, - Comp comp = {}, Proj1 proj1 = {}, - Proj2 proj2 = {}); - template, class Proj1 = identity, class Proj2 = identity> - requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> - constexpr set_symmetric_difference_result, safe_iterator_t, O> - set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + WeaklyIncrementable O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires Mergeable + constexpr ranges::set_symmetric_difference_result + ranges::set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); +template + requires Mergeable, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::set_symmetric_difference_result, safe_iterator_t, O> + ranges::set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7521,17 +7505,15 @@ constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - push_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - push_heap(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::push_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::push_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7574,17 +7556,15 @@ constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - pop_heap(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::pop_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7634,17 +7614,15 @@ constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - make_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - make_heap(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::make_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::make_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7685,17 +7663,15 @@ constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr I - sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, class Proj = identity> - requires Sortable, Comp, Proj> - constexpr safe_iterator_t - sort_heap(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr I + ranges::sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + ranges::sort_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7792,14 +7768,12 @@ \indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr bool ranges::is_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr bool ranges::is_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7829,15 +7803,13 @@ RandomAccessIterator first, RandomAccessIterator last, Compare comp); -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr safe_iterator_t - is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr safe_iterator_t + ranges::is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7867,11 +7839,9 @@ template constexpr const T& min(const T& a, const T& b, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr const T& ranges::min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7903,16 +7873,14 @@ template constexpr T min(initializer_list r, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr T min(initializer_list r, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - requires IndirectlyCopyableStorable, iter_value_t>*> - constexpr iter_value_t> - min(R&& r, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr T ranges::min(initializer_list r, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + requires IndirectlyCopyableStorable, iter_value_t>*> + constexpr iter_value_t> + ranges::min(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7948,11 +7916,9 @@ template constexpr const T& max(const T& a, const T& b, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr const T& ranges::max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7984,16 +7950,14 @@ template constexpr T max(initializer_list r, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr T max(initializer_list r, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - requires IndirectlyCopyableStorable, iter_value_t>*> - constexpr iter_value_t> - max(R&& r, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr T ranges::max(initializer_list r, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + requires IndirectlyCopyableStorable, iter_value_t>*> + constexpr iter_value_t> + ranges::max(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8029,12 +7993,10 @@ template constexpr pair minmax(const T& a, const T& b, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr minmax_result - minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr ranges::minmax_result + ranges::minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} @@ -8067,17 +8029,15 @@ template constexpr pair minmax(initializer_list t, Compare comp); -namespace ranges { - template> Comp = ranges::less<>> - constexpr minmax_result - minmax(initializer_list r, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - requires IndirectlyCopyableStorable, iter_value_t>*> - constexpr minmax_result>> - minmax(R&& r, Comp comp = {}, Proj proj = {}); -} +template> Comp = ranges::less> + constexpr ranges::minmax_result + ranges::minmax(initializer_list r, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + requires IndirectlyCopyableStorable, iter_value_t>*> + constexpr ranges::minmax_result>> + ranges::minmax(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8126,15 +8086,13 @@ ForwardIterator first, ForwardIterator last, Compare comp); -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr safe_iterator_t - min_element(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::min_element(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr safe_iterator_t + ranges::min_element(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8175,15 +8133,13 @@ ForwardIterator first, ForwardIterator last, Compare comp); -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr safe_iterator_t - max_element(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr safe_iterator_t + ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8226,16 +8182,14 @@ minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); -namespace ranges { - template S, class Proj = identity, - IndirectStrictWeakOrder> Comp = ranges::less<>> - constexpr minmax_result - minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); - template, Proj>> Comp = ranges::less<>> - constexpr minmax_result> - minmax_element(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Proj = identity, + IndirectStrictWeakOrder> Comp = ranges::less> + constexpr ranges::minmax_result + ranges::minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); +template, Proj>> Comp = ranges::less> + constexpr ranges::minmax_result> + ranges::minmax_element(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} @@ -8316,22 +8270,20 @@ ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); -namespace ranges { - template S1, InputIterator I2, Sentinel S2, - class Proj1 = identity, class Proj2 = identity, - IndirectStrictWeakOrder, - projected> Comp = ranges::less<>> - constexpr bool - lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, - Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); - template, Proj1>, - projected, Proj2>> Comp = ranges::less<>> - constexpr bool - lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, - Proj1 proj1 = {}, Proj2 proj2 = {}); -} +template S1, InputIterator I2, Sentinel S2, + class Proj1 = identity, class Proj2 = identity, + IndirectStrictWeakOrder, + projected> Comp = ranges::less> + constexpr bool + ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template, Proj1>, + projected, Proj2>> Comp = ranges::less> + constexpr bool + ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -8474,18 +8426,16 @@ constexpr bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr bool - next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); - template, - class Proj = identity> - requires Sortable, Comp, Proj> - constexpr bool - next_permutation(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr bool + ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr bool + ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8529,18 +8479,16 @@ constexpr bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); -namespace ranges { - template S, class Comp = ranges::less<>, - class Proj = identity> - requires Sortable - constexpr bool - prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); - template, - class Proj = identity> - requires Sortable, Comp, Proj> - constexpr bool - prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); -} +template S, class Comp = ranges::less, + class Proj = identity> + requires Sortable + constexpr bool + ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); +template + requires Sortable, Comp, Proj> + constexpr bool + ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8800,6 +8748,12 @@ // \ref{numeric.ops.lcm}, least common multiple template constexpr common_type_t lcm(M m, N n); + + // \ref{numeric.ops.midpoint}, midpoint + template + constexpr T midpoint(T a, T b) noexcept; + template + constexpr T* midpoint(T* a, T* b); } \end{codeblock} @@ -9095,7 +9049,7 @@ shall be convertible to \tcode{T}. \item Neither \tcode{binary_op1} nor \tcode{binary_op2} - shall invalidate subranges, or modify elements in the ranges + shall invalidate subranges, nor modify elements in the ranges \crange{first1}{last1} and \crange{first2}{first2 + (last1 - first1)}. \end{itemize} @@ -9143,7 +9097,7 @@ shall be convertible to \tcode{T}. \item Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate subranges, - or modify elements in the range \crange{first}{last}. + nor modify elements in the range \crange{first}{last}. \end{itemize} \pnum @@ -9458,7 +9412,7 @@ shall be convertible to \tcode{T}. \item Neither \tcode{unary_op} nor \tcode{binary_op} shall - invalidate iterators or subranges, or modify elements in + invalidate iterators or subranges, nor modify elements in the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. \end{itemize} @@ -9775,6 +9729,59 @@ Nothing. \end{itemdescr} +\rSec2[numeric.ops.midpoint]{Midpoint} + +\indexlibrary{\idxcode{midpoint}}% +\begin{itemdecl} +template + constexpr T midpoint(T a, T b) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an arithmetic type other than \tcode{bool}. + +\pnum +\returns +Half the sum of \tcode{a} and \tcode{b}. +If \tcode{T} is an integer type and the sum is odd, +the result is rounded towards \tcode{a}. + +\pnum +\remarks +No overflow occurs. +If \tcode{T} is a floating-point type, at most one inexact operation occurs. +\end{itemdescr} + +\indexlibrary{\idxcode{midpoint}}% +\begin{itemdecl} +template + constexpr T* midpoint(T* a, T* b); +\end{itemdecl} +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a complete object type. + +\pnum +\expects +\tcode{a} and \tcode{b} point to, respectively, +elements $\tcode{x}[i]$ and $\tcode{x}[j]$ of the same array object \tcode{x}. +\begin{note} +An object that is not an array element is considered to belong +to a single-element array for this purpose; see \ref{expr.unary.op}. +A pointer past the last element of an array \tcode{x} of $n$ elements +is considered to be equivalent to a pointer +to a hypothetical element $\tcode{x}[n]$ for this purpose; +see \ref{basic.compound}. +\end{note} + +\pnum +\returns +A pointer to $\tcode{x}[i+\frac{j-i}{2}]$, +where the result of the division is truncated towards zero. +\end{itemdescr} + \rSec1[alg.c.library]{C library algorithms} \pnum diff --git a/source/atomics.tex b/source/atomics.tex index ff4339ec92..51a8c0668c 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -1350,8 +1350,18 @@ \indexlibrary{\idxcode{atomic}}% \pnum -The template argument for -\tcode{T} shall be trivially copyable\iref{basic.types}. \begin{note} Type arguments that are +The template argument for \tcode{T} shall meet the +\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} requirements. +The program is ill-formed if any of +\begin{itemize} +\item \tcode{is_trivially_copyable_v}, +\item \tcode{is_copy_constructible_v}, +\item \tcode{is_move_constructible_v}, +\item \tcode{is_copy_assignable_v}, or +\item \tcode{is_move_assignable_v} +\end{itemize} +is \tcode{false}. +\begin{note} Type arguments that are not also statically initializable may be difficult to use. \end{note} \pnum diff --git a/source/basic.tex b/source/basic.tex index af3c0804d0..a7e73e817a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -99,7 +99,7 @@ one or more names into a translation unit or redeclare names introduced by previous declarations. If so, the -declaration specifies the interpretation and attributes of these names. +declaration specifies the interpretation and semantic properties of these names. A declaration may also have effects including: \begin{itemize} \item a static assertion\iref{dcl.dcl}, @@ -135,7 +135,7 @@ \item it declares a static data member outside a class definition and the variable was defined within the class with the \tcode{constexpr} -specifier (this usage is deprecated; see \ref{depr.static_constexpr}), +specifier (this usage is deprecated; see \ref{depr.static.constexpr}), \item \indextext{declaration!class name}% it is introduced by an \grammarterm{elaborated-type-specifier}\iref{class.name}, @@ -274,13 +274,16 @@ \rSec1[basic.def.odr]{One-definition rule} \pnum -No translation unit shall contain more than one definition of any -variable, function, class type, enumeration type, or template. +A variable, function, class type, enumeration type, or template +shall not be defined where a prior definition is necessarily reachable\iref{module.reach}; +no diagnostic is required if the prior declaration is in another translation unit. \pnum \indextext{expression!potentially evaluated}% -An expression is \defn{potentially evaluated} unless it is an -unevaluated operand\iref{expr.prop} or a subexpression thereof. +An expression or conversion is \defn{potentially evaluated} unless it is +an unevaluated operand\iref{expr.prop}, +a subexpression thereof, or +a conversion in an initialization or conversion sequence in such a context. The set of \defn{potential results} of an expression \tcode{e} is defined as follows: \begin{itemize} @@ -290,12 +293,17 @@ \item If \tcode{e} is a subscripting operation\iref{expr.sub} with an array operand, the set contains the potential results of that operand. \item If \tcode{e} is a class member access -expression\iref{expr.ref}, the set contains the potential results of -the object expression. +expression\iref{expr.ref} of the form +\tcode{e1 . \opt{template} e2} +naming a non-static data member, +the set contains the potential results of \tcode{e1}. +\item if \tcode{e} is a class member access expression +naming a static data member, +the set contains the \grammarterm{id-expression} designating the data member. \item If \tcode{e} is a pointer-to-member -expression\iref{expr.mptr.oper} whose second operand is a constant -expression, the set contains the potential results of the object -expression. +expression\iref{expr.mptr.oper} of the form +\tcode{e1 .* e2}, +the set contains the potential results of \tcode{e1}. \item If \tcode{e} has the form \tcode{(e1)}, the set contains the potential results of \tcode{e1}. \item If \tcode{e} is a glvalue conditional @@ -322,48 +330,62 @@ \end{note} \pnum -\indextext{function!named by an expression}% -A function is \defn{named by an expression} as follows: +A function is \defnx{named by}{function!named by expression or conversion} +an expression or conversion as follows: \begin{itemize} \item - A function whose name appears in an expression - is named by that expression - if it is the unique lookup result or the selected member - of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}), + A function is named by an expression or conversion + if it is the unique result of a name lookup or the selected member + of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}) + in an overload resolution performed + as part of forming that expression or conversion, unless it is a pure virtual function and either - its name is not explicitly qualified or + the expression is not an \grammarterm{id-expression} naming the function with + an explicitly qualified name or the expression forms a pointer to member\iref{expr.unary.op}. \begin{note} This covers taking the address of functions~(\ref{conv.func}, \ref{expr.unary.op}), calls to named functions\iref{expr.call}, operator overloading\iref{over}, user-defined conversions\iref{class.conv.fct}, - allocation functions for placement \grammarterm{new-expression}{s}\iref{expr.new}, as well as + allocation functions for \grammarterm{new-expression}{s}\iref{expr.new}, as well as non-default initialization\iref{dcl.init}. A constructor selected to copy or move an object of class type - is considered to be named by an expression + is considered to be named by an expression or conversion even if the call is actually elided by the implementation\iref{class.copy.elision}. \end{note} \item - An allocation or deallocation function for a class + A deallocation function for a class is named by a \grammarterm{new-expression} - as specified in~\ref{expr.new} and~\ref{class.free}. + if it is the single matching deallocation function + for the allocation function selected by overload resolution, + as specified in~\ref{expr.new}. \item A deallocation function for a class - is named by a delete expression + is named by a \grammarterm{delete-expression} + if it is the selected usual deallocation function as specified in~\ref{expr.delete} and~\ref{class.free}. \end{itemize} \pnum A variable \tcode{x} whose name appears as a -potentially-evaluated expression \tcode{ex} is \defnx{odr-used}{odr-use} by \tcode{ex} unless -applying the lvalue-to-rvalue conversion\iref{conv.lval} to \tcode{x} yields -a constant expression\iref{expr.const} -that does not invoke a function -other than a trivial special member function\iref{special} -and, if \tcode{x} is an object, \tcode{ex} is an element of -the set of potential results of an expression \tcode{e}, where either the lvalue-to-rvalue -conversion\iref{conv.lval} is applied to \tcode{e}, or \tcode{e} is -a discarded-value expression\iref{expr.prop}. +potentially-evaluated expression \tcode{e} +is \defnx{odr-used}{odr-use} by \tcode{e} unless +\begin{itemize} +\item + \tcode{x} is a reference that is + usable in constant expressions\iref{expr.const}, or +\item + \tcode{x} is a variable of non-reference type that is + usable in constant expressions and has no mutable subobjects, and + \tcode{e} is an element of the set of potential results of an expression + of non-volatile-qualified non-class type + to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or +\item + \tcode{x} is a variable of non-reference type, and + \tcode{e} is an element of the set of potential results + of a discarded-value expression\iref{expr.prop} + to which the lvalue-to-rvalue conversion is not applied. +\end{itemize} \pnum A structured binding is odr-used if it appears as a potentially-evaluated expression. @@ -376,7 +398,8 @@ \pnum A virtual member function is odr-used if it is not pure. -A function is odr-used if it is named by a potentially-evaluated expression. +A function is odr-used if it is named by +a potentially-evaluated expression or conversion. A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the @@ -401,8 +424,7 @@ is \defn{odr-usable} in a declarative region\iref{basic.scope.declarative} if: \begin{itemize} -\item the local entity is either -not \tcode{*this}, or +\item either the local entity is not \tcode{*this}, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and @@ -415,7 +437,10 @@ \begin{itemize} \item the intervening declarative region is a block scope, or \item the intervening declarative region is the function parameter scope of a \grammarterm{lambda-expression} -that has a \grammarterm{simple-capture} naming the entity or has a \grammarterm{capture-default}. +that has a \grammarterm{simple-capture} +naming the entity or has a \grammarterm{capture-default}, and +the block scope of the \grammarterm{lambda-expression} +is also an intervening declarative region. \end{itemize} \end{itemize} @@ -425,11 +450,13 @@ \begin{example} \begin{codeblock} void f(int n) { - [] { n = 1; }; // error, \tcode{n} is not odr-usable due to intervening lambda-expression + [] { n = 1; }; // error: \tcode{n} is not odr-usable due to intervening lambda-expression struct A { - void f() { n = 2; } // error, \tcode{n} is not odr-usable due to intervening function definition scope + void f() { n = 2; } // error: \tcode{n} is not odr-usable due to intervening function definition scope }; - void g(int = n); // error, \tcode{n} is not odr-usable due to intervening function parameter scope + void g(int = n); // error: \tcode{n} is not odr-usable due to intervening function parameter scope + [=](int k = n) {}; // error: \tcode{n} is not odr-usable due to being + // outside the block scope of the \grammarterm{lambda-expression} [&] { [n]{ return n; }; }; // OK } \end{codeblock} @@ -443,12 +470,27 @@ the standard or a user-defined library, or (when appropriate) it is implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor}, \ref{class.dtor}, and \ref{class.copy.assign}). -An inline function or variable shall be defined in every +A definition of an inline function or variable shall be reachable in every translation unit in which it is odr-used outside of a discarded statement. +\begin{example} +\begin{codeblock} +auto f() { + struct A {}; + return A{}; +} +decltype(f()) g(); +auto x = g(); +\end{codeblock} +A program containing this translation unit is ill-formed +because \tcode{g} is odr-used but not defined, +and cannot be defined in any other translation unit +because the local class \tcode{A} cannot be named outside this +translation unit. +\end{example} \pnum \indextext{type!incomplete}% -Exactly one definition of a class is required in a translation unit if +A definition of a class is required to be reachable in every context in which the class is used in a way that requires the class type to be complete. \begin{example} The following complete translation unit is well-formed, even though it never defines \tcode{X}: @@ -506,9 +548,17 @@ static data member of a class template\iref{temp.static}, member function of a class template\iref{temp.mem.func}, or template specialization for which some template parameters are not -specified~(\ref{temp.spec}, \ref{temp.class.spec}) in a program provided -that each definition appears in a different translation unit, and -provided the definitions satisfy the following requirements. Given such +specified~(\ref{temp.spec}, \ref{temp.class.spec}) in a program +provided that +no prior definition is necessarily reachable\iref{module.reach} +at the point where a definition appears, and +provided the definitions satisfy the following requirements. +There shall not be more than one definition +of an entity +that is attached to a named module\iref{module.unit}; +no diagnostic is required unless a prior definition +is reachable at a point where a later definition appears. +Given such an entity named \tcode{D} defined in more than one translation unit, then \begin{itemize} @@ -681,9 +731,13 @@ all refer to the same variable, non-static data member, or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is -hidden\iref{basic.scope.hiding}. \begin{note} A namespace name or a -class template name must be unique in its declarative -region~(\ref{namespace.alias}, \ref{temp}). \end{note} +hidden\iref{basic.scope.hiding}. +\begin{note} +A structured binding\iref{dcl.struct.bind}, +namespace name\iref{basic.namespace}, or +class template name\iref{temp} +must be unique in its declarative region. +\end{note} \end{itemize} \begin{note} These restrictions apply to the declarative region into which a name is introduced, which is not necessarily the same as the region in @@ -939,7 +993,8 @@ \grammarterm{using-directive}\iref{namespace.udir} that nominates the member's namespace, the member's potential scope includes that portion of the potential scope of the \grammarterm{using-directive} that follows -the member's point of declaration. \begin{example} +the member's point of declaration. +\begin{example} \begin{codeblock} namespace N { @@ -967,6 +1022,42 @@ \end{codeblock} \end{example} +\pnum +If a translation unit $Q$ is imported into a translation unit $R$\iref{module.import}, +the potential scope of a name $X$ declared with namespace scope in $Q$ +is extended to include the portion of the corresponding namespace +scope in $R$ following the first \grammarterm{module-import-declaration} +or \grammarterm{module-declaration} +in $R$ that imports $Q$ (directly or indirectly) if +\begin{itemize} +\item $X$ does not have internal linkage, and +\item $X$ is declared after the \grammarterm{module-declaration} in $Q$ (if any), and +\item either $X$ is exported or $Q$ and $R$ are part of the same module. +\end{itemize} +\begin{note} +A \grammarterm{module-import-declaration} imports both +the named translation unit(s) and +any modules named by exported +\grammarterm{module-import-declaration}{s} within them, +recursively. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module Q; +export int sq(int i) { return i*i; } +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module R; +export import Q; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +import R; +int main() { return sq(9); } // OK: \tcode{sq} from module \tcode{Q} +\end{codeblocktu} +\end{example} +\end{note} + \pnum A namespace member can also be referred to after the \tcode{::} scope resolution operator\iref{expr.prim.id.qual} applied to the name of its @@ -1205,8 +1296,10 @@ are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access -checking have succeeded are the attributes introduced by the name's -declaration used further in expression processing\iref{expr}. +checking have succeeded +are the semantic properties introduced by the name's declaration +and its reachable\iref{module.reach} redeclarations +used further in expression processing\iref{expr}. \pnum A name ``looked up in the context of an expression'' is looked up @@ -1590,51 +1683,69 @@ \end{example} \pnum -For each argument type \tcode{T} in the function call, there is a set of -zero or more \defnx{associated namespaces}{namespace!associated} -and a set of zero or more \defnx{associated classes}{class!associated} -to be considered. The sets of namespaces and classes are -determined entirely by the types of the function arguments (and the -namespace of any template template argument). Typedef names and -\grammarterm{using-declaration}{s} used to specify the types do not -contribute to this set. The sets of namespaces and classes are -determined in the following way: +For each argument type \tcode{T} in the function call, +there is a set of zero or more +\defnx{associated namespaces}{namespace!associated} +and a set of zero or more +\defnx{associated entities}{entity!associated} +(other than namespaces) +to be considered. +The sets of namespaces and entities +are determined entirely by +the types of the function arguments +(and the namespace of any template template argument). +Typedef names and \grammarterm{using-declaration}{s} +used to specify the types +do not contribute to this set. +The sets of namespaces and entities +are determined in the following way: \begin{itemize} \item If \tcode{T} is a fundamental type, its associated sets of -namespaces and classes are both empty. - -\item If \tcode{T} is a class type (including unions), its associated -classes are: the class itself; the class of which it is a member, if -any; and its direct and indirect base classes. Its associated namespaces -are the innermost enclosing namespaces of its associated classes. -Furthermore, if \tcode{T} is a class template specialization, its -associated namespaces and classes also include: the namespaces and -classes associated with the types of the template arguments provided for -template type parameters (excluding template template parameters); the -namespaces of which any template template arguments are members; and the +namespaces and entities are both empty. + +\item If \tcode{T} is a class type (including unions), +its associated entities are: +the class itself; +the class of which it is a member, if any; +and its direct and indirect base classes. +Its associated namespaces are +the innermost enclosing namespaces of its associated entities. +Furthermore, if \tcode{T} is a class template specialization, +its associated namespaces and entities also include: +the namespaces and entities +associated with the types of the template arguments +provided for template type parameters +(excluding template template parameters); +the templates used as template template arguments; +the namespaces of which any template template arguments are members; and the classes of which any member templates used as template template -arguments are members. \begin{note} Non-type template arguments do not -contribute to the set of associated namespaces.\end{note} +arguments are members. +\begin{note} +Non-type template arguments do not +contribute to the set of associated namespaces. +\end{note} -\item If \tcode{T} is an enumeration type, its associated namespace is -the innermost enclosing namespace of its declaration. If it is a class member, its -associated class is the member's class; else it has no associated class. +\item If \tcode{T} is an enumeration type, +its associated namespace is +the innermost enclosing namespace of its declaration, and +its associated entities are \tcode{T} +and, if it is a class member, the member's class. \item If \tcode{T} is a pointer to \tcode{U} or an array of \tcode{U}, -its associated namespaces and classes are those associated with +its associated namespaces and entities are those associated with \tcode{U}. \item If \tcode{T} is a function type, its associated namespaces and -classes are those associated with the function parameter types and those +entities are those associated with the function parameter types and those associated with the return type. \item If \tcode{T} is a pointer to a member function of a class -\tcode{X}, its associated namespaces and classes are those associated +\tcode{X}, its associated namespaces and entities are those associated with the function parameter types and return type, together with those associated with \tcode{X}. \item If \tcode{T} is a pointer to a data member of class \tcode{X}, its -associated namespaces and classes are those associated with the member +associated namespaces and entities are those associated with the member type together with those associated with \tcode{X}. \end{itemize} If an associated namespace is an inline namespace\iref{namespace.def}, its @@ -1642,12 +1753,12 @@ directly contains inline namespaces, those inline namespaces are also included in the set. In addition, if the argument is the name or address of a set of -overloaded functions and/or function templates, its associated classes +overloaded functions and/or function templates, its associated entities and namespaces are the union of those associated with each of the -members of the set, i.e., the classes and namespaces associated with its +members of the set, i.e., the entities and namespaces associated with its parameter types and return type. Additionally, if the aforementioned set of overloaded functions is named with -a \grammarterm{template-id}, its associated classes and namespaces also include +a \grammarterm{template-id}, its associated entities and namespaces also include those of its type \grammarterm{template-argument}{s} and its template \grammarterm{template-argument}{s}. @@ -1663,8 +1774,8 @@ then \placeholder{Y} is empty. Otherwise \placeholder{Y} is the set of declarations found in the namespaces associated with the argument types as described below. The set of declarations found by the lookup of the name is the -union of \placeholder{X} and \placeholder{Y}. \begin{note} The namespaces and classes -associated with the argument types can include namespaces and classes +union of \placeholder{X} and \placeholder{Y}. \begin{note} The namespaces and entities +associated with the argument types can include namespaces and entities already considered by the ordinary unqualified lookup. \end{note} \begin{example} @@ -1685,22 +1796,83 @@ \end{example} \pnum -When considering an associated namespace, the lookup is the same as the -lookup performed when the associated namespace is used as a -qualifier\iref{namespace.qual} except that: +When considering an associated namespace \tcode{N}, +the lookup is the same as the +lookup performed when \tcode{N} +is used as a qualifier\iref{namespace.qual} +except that: \begin{itemize} -\item Any \grammarterm{using-directive}{s} in the associated namespace are -ignored. +\item Any \grammarterm{using-directive}{s} in \tcode{N} are ignored. + +\item All names except those of (possibly overloaded) functions and +function templates are ignored. \item Any namespace-scope friend functions or friend function templates\iref{class.friend} -declared in associated classes are visible within their respective +declared in classes with reachable definitions in the set of associated entities +are visible within their respective namespaces even if they are not visible during an ordinary lookup\iref{namespace.memdef}. -\item All names except those of (possibly overloaded) functions and -function templates are ignored. +\item +Any declaration \tcode{D} in \tcode{N} +that is in the interface of +a named module \tcode{M}\iref{module.interface} +is visible +if there is an associated entity attached to \tcode{M} +with the same innermost enclosing non-inline namespace as \tcode{D}. + +\item +If the lookup is for a dependent name (\ref{temp.dep}, \ref{temp.dep.candidate}), +any declaration \tcode{D} in \tcode{N} +is visible +if \tcode{D} would be visible to qualified name lookup\iref{namespace.qual} +at any point in the instantiation context\iref{module.context} of the lookup, +unless \tcode{D} is declared in another translation unit, attached to the global module, +and is either discarded\iref{module.global} or has internal linkage. \end{itemize} +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M; +namespace R { + export struct X {}; + export void f(X); +} +namespace S { + export void f(X, X); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module N; +import M; +export R::X make(); +namespace R { static int g(X); } +template void apply(T t, U u) { + f(t, u); + g(t); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +module Q; +import N; +namespace S { + struct Z { template operator T(); }; +} +void test() { + auto x = make(); // OK, \tcode{decltype(x)} is \tcode{R::X} in module \tcode{M} + R::f(x); // ill-formed: \tcode{R} and \tcode{R::f} are not visible here + f(x); // OK, calls \tcode{R::f} from interface of \tcode{M} + f(x, S::Z()); // ill-formed: \tcode{S::f} in module \tcode{M} not considered + // even though \tcode{S} is an associated namespace + apply(x, S::Z()); // OK, \tcode{S::f} is visible in instantiation context, and + // \tcode{R::g} is visible even though it has internal linkage +} +\end{codeblocktu} +\end{example} + \rSec2[basic.lookup.qual]{Qualified name lookup} \pnum @@ -1899,7 +2071,11 @@ For a namespace \tcode{X} and name \tcode{m}, the namespace-qualified lookup set $S(X, m)$ is defined as follows: Let $S'(X, m)$ be the set of all declarations of \tcode{m} in \tcode{X} and the inline namespace set of -\tcode{X}\iref{namespace.def}. If $S'(X, m)$ is not empty, $S(X, m)$ +\tcode{X}\iref{namespace.def} +whose potential scope\iref{basic.scope.namespace} +would include the namespace in which \tcode{m} is declared +at the location of the \grammarterm{nested-name-specifier}. +If $S'(X, m)$ is not empty, $S(X, m)$ is $S'(X, m)$; otherwise, $S(X, m)$ is the union of $S(N_i, m)$ for all namespaces $N_i$ nominated by \grammarterm{using-directive}{s} in \tcode{X} and its inline namespace set. @@ -2046,7 +2222,7 @@ During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of the member, and if one declaration introduces a class name or enumeration name and the other declarations -either introduce the same variable, the same enumerator or a set of +introduce either the same variable, the same enumerator, or a set of functions, the non-type name hides the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the declarations are from different namespaces), the program is ill-formed. @@ -2321,9 +2497,42 @@ \begin{bnf} \nontermdef{translation-unit}\br - \opt{declaration-seq} + \opt{top-level-declaration-seq}\br + \opt{global-module-fragment} module-declaration \opt{top-level-declaration-seq} \opt{private-module-fragment} +\end{bnf} + +\begin{bnf} +\nontermdef{private-module-fragment}\br + \keyword{module} \terminal{:} \keyword{private} \terminal{;} \opt{top-level-declaration-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{top-level-declaration-seq}\br + top-level-declaration\br + top-level-declaration-seq top-level-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{top-level-declaration}\br + module-import-declaration\br + declaration \end{bnf} +\pnum +A \grammarterm{private-module-fragment} shall appear only +in a primary module interface unit\iref{module.unit}. +A module unit with a \grammarterm{private-module-fragment} +shall be the only module unit of its module; +no diagnostic is required. + +\pnum +A token sequence beginning with +\opt{\tcode{export}} \tcode{module} or +\opt{\tcode{export}} \tcode{import} +and not immediately followed by \tcode{::} +is never interpreted as the \grammarterm{declaration} +of a \grammarterm{top-level-declaration}. + \pnum \indextext{linkage}% \indextext{translation unit}% @@ -2338,6 +2547,11 @@ can be referred to by names from scopes of other translation units or from other scopes of the same translation unit. +\item When a name has \defnx{module linkage}{linkage!module}, +the entity it denotes +can be referred to by names from other scopes of the same module unit\iref{module.unit} or +from scopes of other module units of that same module. + \item When a name has \indextext{linkage!internal}\defn{internal linkage}, the entity it denotes can be referred to by names from other scopes in the same translation @@ -2358,22 +2572,30 @@ linkage if it is the name of \begin{itemize} \item - a variable, function or function template that is - explicitly declared \tcode{static}; or, + a variable, variable template, function, or function template that is + explicitly declared \tcode{static}; or \item - a non-inline variable of non-volatile const-qualified type that is - neither explicitly declared \tcode{extern} nor previously - declared to have external linkage; or + a non-template variable of non-volatile const-qualified type, unless + \begin{itemize} + \item it is explicitly declared \tcode{extern}, or + \item it is inline or exported, or + \item it was previously declared and the prior declaration did + not have internal linkage; or + \end{itemize} \item a data member of an anonymous union. \end{itemize} +\begin{note} +An instantiated variable template that has const-qualified type +can have external or module linkage, even if not declared \tcode{extern}. +\end{note} \pnum An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above -has the same linkage as the enclosing namespace if it is the name of +and that is the name of \begin{itemize} \item a variable; or \item a function; or @@ -2385,7 +2607,22 @@ a named enumeration\iref{dcl.enum}, or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes\iref{dcl.typedef}; or -\item a template. +\item a template +\end{itemize} +has its linkage determined as follows: +\begin{itemize} +\item +if the enclosing namespace has internal linkage, +the name has internal linkage; +\item +otherwise, +if the declaration of the name is +attached to a named module\iref{module.unit} +and is not exported\iref{module.interface}, +the name has module linkage; +\item +otherwise, +the name has external linkage. \end{itemize} \pnum @@ -2397,10 +2634,18 @@ member. \pnum -The name of a function declared in block scope and the name of a variable declared by a -block scope \tcode{extern} declaration have linkage. If there is a visible declaration -of an entity with linkage having the same name and type, ignoring entities declared -outside the innermost enclosing namespace scope, the block scope declaration declares +The name of a function declared in block scope and +the name of a variable declared by a block scope \tcode{extern} declaration +have linkage. +If such a declaration is attached to a named module, +the program is ill-formed. +If there is a visible declaration +of an entity with linkage, ignoring entities declared +outside the innermost enclosing namespace scope, +such that the block scope declaration would be +a (possibly ill-formed) redeclaration +if the two declarations appeared in the same declarative region, +the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage. @@ -2409,9 +2654,11 @@ \begin{example} \begin{codeblock} static void f(); +extern "C" void h(); static int i = 0; // \#1 void g() { extern void f(); // internal linkage + extern void h(); // C language linkage int i; // \#2: \tcode{i} has no linkage { extern void f(); // internal linkage @@ -2456,63 +2703,15 @@ noted, a name declared at block scope\iref{basic.scope.block} has no linkage. -\pnum -A type is said to have linkage if and only if: -\begin{itemize} -\item it is a class or enumeration type that is named (or has a name for -linkage purposes\iref{dcl.typedef}) and the name has linkage; or - -\item it is an unnamed class or unnamed enumeration that is a member of a class -with linkage; or - -\item it is a specialization of a class template\iref{temp}\footnote{A class -template has the linkage of the innermost enclosing class or namespace in which -it is declared.}; -or - -\item it is a fundamental type\iref{basic.fundamental}; or - -\item it is a compound type\iref{basic.compound} other than a class or -enumeration, compounded exclusively from types that have linkage; or - -\item it is a cv-qualified\iref{basic.type.qualifier} version of a -type that has linkage. -\end{itemize} -\begin{note} -In other words, a type without linkage contains a class or enumeration that -cannot be named outside its translation unit. -Classes with linkage may contain members -whose types do not have linkage. -Typedef names are ignored in the determination -of whether a type has linkage. -\end{note} - -\begin{example} -\begin{codeblock} -template struct B { - void g(T) { } - void h(T); - friend void i(B, T) { } -}; - -void f() { - struct A { int x; }; // no linkage - A a = { 1 }; - B ba; // declares \tcode{B::g(A)} and \tcode{B::h(A)} - ba.g(a); // OK - ba.h(a); // error: \tcode{B::h(A)} not defined; \tcode{A} cannot be named in another translation unit - i(ba, a); // OK -} -\end{codeblock} -\end{example} - \pnum Two names that are the same\iref{basic} and that are declared in different scopes shall denote the same variable, function, type, template or namespace if \begin{itemize} -\item both names have external linkage or else both names have internal -linkage and are declared in the same translation unit; and +\item both names have external or module linkage +and are declared in declarations attached to the same module, +or else both names have internal linkage +and are declared in the same translation unit; and \item both names refer to members of the same namespace or to members, not by inheritance, of the same class; and @@ -2523,6 +2722,48 @@ \item when both names denote function templates, the signatures\iref{temp.over.link} are the same. \end{itemize} +If multiple declarations of the same name with external linkage +would declare the same entity except that +they are attached to different modules, +the program is ill-formed; no diagnostic is required. +\begin{note} +\grammarterm{using-declaration}{s}, +typedef declarations, +and \grammarterm{alias-declaration}{s} +do not declare entities, but merely introduce synonyms. +Similarly, +\grammarterm{using-directive}{s} +do not declare entities. +\end{note} + +\pnum +If a declaration would redeclare a reachable declaration +attached to a different module, the program is ill-formed. +\begin{example} +\begin{codeblocktu}{\tcode{"decls.h"}} +int f(); // \#1, attached to the global module +int g(); // \#2, attached to the global module +\end{codeblocktu} + +\begin{codeblocktu}{Module interface of \tcode{M}} +module; +#include "decls.h" +export module M; +export using ::f; // OK: does not declare an entity, exports \#1 +int g(); // error: matches \#2, but attached to \tcode{M} +export int h(); // \#3 +export int k(); // \#4 +\end{codeblocktu} + +\begin{codeblocktu}{Other translation unit} +import M; +static int h(); // error: matches \#3 +int k(); // error: matches \#4 +\end{codeblocktu} +\end{example} +As a consequence of these rules, +all declarations of an entity are attached to the same module; +the entity is said to be \defnx{attached}{attached!entity} to that module. \pnum \indextext{consistency!type declaration}% @@ -2837,15 +3078,17 @@ \indextext{object lifetime|(}% The \defn{lifetime} of an object or reference is a runtime property of the object or reference. -An object is said to have \defnadj{non-vacuous}{initialization} if it is of a class or -array type and it or one of its subobjects is initialized by a constructor -other than a trivial default constructor. \begin{note} Initialization by a -trivial copy/move constructor is non-vacuous initialization. \end{note} +\indextext{initialization!vacuous}% +A variable is said to have \defn{vacuous initialization} +if it is default-initialized and, +if it is of class type or a (possibly multi-dimensional) array thereof, +that class type has a trivial default constructor. The lifetime of an object of type \tcode{T} begins when: \begin{itemize} -\item storage with the proper alignment and size for type \tcode{T} is -obtained, and -\item if the object has non-vacuous initialization, its initialization is complete, +\item storage with the proper alignment and size + for type \tcode{T} is obtained, and +\item its initialization (if any) is complete + (including vacuous initialization)\iref{dcl.init}, \end{itemize} except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the @@ -2853,8 +3096,8 @@ or as described in \ref{class.union}. The lifetime of an object \placeholder{o} of type \tcode{T} ends when: \begin{itemize} -\item if \tcode{T} is a class type with a non-trivial -destructor\iref{class.dtor}, the destructor call starts, or +\item if \tcode{T} is a non-class type, the object is destroyed, or +\item if \tcode{T} is a class type, the destructor call starts, or \item the storage which the object occupies is released, or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. \end{itemize} @@ -3412,7 +3655,9 @@ \pnum A global allocation function is only called as the result of a new expression\iref{expr.new}, or called directly using the function call -syntax\iref{expr.call}, or called indirectly through calls to the +syntax\iref{expr.call}, or called indirectly to allocate storage for +a coroutine state\iref{dcl.fct.def.coroutine}, +or called indirectly through calls to the functions in the \Cpp{} standard library. \begin{note} In particular, a global allocation function is not called to allocate storage for objects with static storage duration\iref{basic.stc.static}, for objects or references @@ -3916,6 +4161,12 @@ \item A temporary object bound to a reference parameter in a function call\iref{expr.call} persists until the completion of the full-expression containing the call. +\item A temporary object bound to a reference element of +an aggregate of class type initialized from +a parenthesized \grammarterm{expression-list}\iref{dcl.init} +persists until the completion of the full-expression +containing the \grammarterm{expression-list}. + \item The lifetime of a temporary bound to the returned value in a function \tcode{return} statement\iref{stmt.return} is not extended; the temporary is destroyed at the end of the full-expression in the \tcode{return} statement. \item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. @@ -4261,7 +4512,7 @@ \defnx{signed integer types}{signed integer type}. The range of representable values for a signed integer type is $-2^{N-1}$ to $2^{N-1}-1$ (inclusive), -where \placeholder{N} is called the \defn{range exponent} of the type. +where \placeholder{N} is called the \defn{width} of the type. \indextext{integral type!implementation-defined \tcode{sizeof}}% \begin{note} Plain \tcode{int}s are intended to have @@ -4289,7 +4540,7 @@ there exists a corresponding \defn{extended unsigned integer type}. The standard and extended unsigned integer types are collectively called \defnx{unsigned integer types}{unsigned integer type}. -An unsigned integer type has the same range exponent \placeholder{N} +An unsigned integer type has the same width \placeholder{N} as the corresponding signed integer type. \indextext{arithmetic!\idxcode{unsigned}}% The range of representable values for the unsigned type is @@ -4317,9 +4568,9 @@ the largest value of the corresponding unsigned type. \end{example} -\begin{floattable}{Minimum range exponent}{tab:range.exponent}{ll} +\begin{floattable}{Minimum width}{tab:width}{ll} \topline -\lhdr{Type} & \rhdr{Minimum range exponent $N$} \\ +\lhdr{Type} & \rhdr{Minimum width $N$} \\ \capsep \tcode{signed char} & 8 \\ \tcode{short} & 16 \\ @@ -4329,10 +4580,10 @@ \end{floattable} \pnum -The range exponent of each signed integer type -shall not be less than the values specified in \tref{range.exponent}. +The width of each signed integer type +shall not be less than the values specified in \tref{width}. The value representation of a signed or unsigned integer type -comprises $N$ bits, where N is the respective range exponent. +comprises $N$ bits, where N is the respective width. Each set of values for any padding bits\iref{basic.types} in the object representation are alternative representations of the value specified by the value representation. @@ -4345,11 +4596,11 @@ the constraints given in ISO C 5.2.4.2.1. \end{note} Except as specified above, -the range exponent of a signed or unsigned integer type is -\impldef{range exponent of integral type}. +the width of a signed or unsigned integer type is +\impldef{width of integral type}. \pnum -Each value $x$ of an unsigned integer type with range exponent $N$ has +Each value $x$ of an unsigned integer type with width $N$ has a unique representation $x = x_0 2^0 + x_1 2^1 + \ldots + x_{N-1} 2^{N-1}$, where each coefficient $x_i$ is either 0 or 1; this is called the \defn{base-2 representation} of $x$. @@ -4401,7 +4652,7 @@ \end{note} \begin{note} A bit-field of narrow character type whose width is larger than -the range exponent of that type has padding bits; see \ref{basic.types}. +the width of that type has padding bits; see \ref{basic.types}. \end{note} \pnum @@ -4853,7 +5104,7 @@ duration\iref{basic.stc.auto} is associated with each entry into its block. Such an object exists and retains its last-stored value during the execution of the block and while the block is suspended (by a call -of a function or receipt of a signal). +of a function, suspension of a coroutine\iref{expr.await}, or receipt of a signal). \pnum A \defn{constituent expression} is defined as follows: @@ -5702,7 +5953,8 @@ \pnum \indextext{program!start|(}% -A program shall contain a global function called \tcode{main}. +A program shall contain a global function called \tcode{main} +attached to the global module. Executing a program starts a main thread of execution~(\ref{intro.multithread}, \ref{thread.threads}) in which the \tcode{main} function is invoked, and in which variables of static storage duration @@ -5755,10 +6007,13 @@ \impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as deleted or that declares \tcode{main} to be \tcode{inline}, \tcode{static}, or \tcode{constexpr} is ill-formed. +The function \tcode{main} shall not be a coroutine\iref{dcl.fct.def.coroutine}. The \tcode{main} function shall not be declared with a -\grammarterm{linkage-specification}\iref{dcl.link}. A program that -declares a variable \tcode{main} at global scope or that declares the name -\tcode{main} with C language linkage (in any namespace) is ill-formed. +\grammarterm{linkage-specification}\iref{dcl.link}. +A program that declares a variable \tcode{main} at global scope, +or that declares a function \tcode{main} at global scope attached to a named module, +or that declares the name \tcode{main} with C language linkage (in any namespace) +is ill-formed. The name \tcode{main} is not otherwise reserved. \begin{example} Member functions, classes, and enumerations can be called \tcode{main}, as can entities in other @@ -6009,26 +6264,25 @@ \indextext{program!termination|(}% \indextext{object!destructor static}% \indextext{\idxcode{main} function!return from}% -Destructors\iref{class.dtor} for initialized objects -(that is, objects whose lifetime\iref{basic.life} has begun) -with static storage duration, -and functions registered with \tcode{std::atexit}, +Constructed objects\iref{dcl.init} +with static storage duration are destroyed +and functions registered with \tcode{std::atexit} are called as part of a call to \indextext{\idxcode{exit}}% \indexlibrary{\idxcode{exit}}% \tcode{std::exit}\iref{support.start.term}. The call to \tcode{std::exit} is sequenced before -the invocations of the destructors and the registered functions. +the destructions and the registered functions. \begin{note} Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. \end{note} \pnum -Destructors for initialized objects with thread storage duration within a given thread -are called as a result of returning from the initial function of that thread and as a +Constructed objects with thread storage duration within a given thread +are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling \tcode{std::exit}. -The completions of the destructors for all initialized objects with thread storage -duration within that thread strongly happen before the initiation of the destructors of +The destruction of all constructed objects with thread storage +duration within that thread strongly happens before destroying any object with static storage duration. \pnum diff --git a/source/classes.tex b/source/classes.tex index 26432ad745..41d1654433 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -45,14 +45,14 @@ \begin{bnf} \nontermdef{class-virt-specifier}\br - \terminal{final} + \keyword{final} \end{bnf} \begin{bnf} \nontermdef{class-key}\br - \terminal{class}\br - \terminal{struct}\br - \terminal{union} + \keyword{class}\br + \keyword{struct}\br + \keyword{union} \end{bnf} A class declaration where the \grammarterm{class-name} @@ -470,8 +470,8 @@ \begin{bnf} \nontermdef{virt-specifier}\br - \terminal{override}\br - \terminal{final} + \keyword{override}\br + \keyword{final} \end{bnf} \begin{bnf} @@ -854,8 +854,7 @@ declaration in the class definition or its definition outside of the class definition declares the function as \tcode{inline} or \tcode{constexpr}. \begin{note} -Member functions of a class in namespace scope have the linkage of that class. -Member functions of a local class\iref{class.local} have no linkage. +Member functions of a class have the linkage of the name of the class. See~\ref{basic.link}. \end{note} @@ -1307,6 +1306,9 @@ \indextext{constructor!address of}% The address of a constructor shall not be taken. +\pnum +A constructor shall not be a coroutine. + \rSec3[class.default.ctor]{Default constructors} \pnum @@ -1343,7 +1345,8 @@ of reference type, \item any non-variant non-static data member of const-qualified type (or array -thereof) with no \grammarterm{brace-or-equal-initializer} does not have a user-provided default constructor, +thereof) with no \grammarterm{brace-or-equal-initializer} +is not const-default-constructible\iref{dcl.init}. \item \tcode{X} is a union and all of its variant members are of const-qualified type (or array thereof), @@ -2121,7 +2124,6 @@ \tcode{virtual}. \pnum -A destructor is used to destroy objects of its class type. \indextext{restriction!destructor}% The address of a destructor shall not be taken. \indextext{\idxcode{const}!destructor and}% @@ -2396,6 +2398,9 @@ \end{codeblock} \end{note} +\pnum +A destructor shall not be a coroutine. + \rSec2[class.conv]{Conversions} \pnum @@ -2545,7 +2550,7 @@ \begin{bnf} \nontermdef{conversion-function-id}\br - \terminal{operator} conversion-type-id + \keyword{operator} conversion-type-id \end{bnf} \begin{bnf} @@ -2832,7 +2837,7 @@ and may specify a \grammarterm{brace-or-equal-initializer}. If the member is declared with the \tcode{constexpr} specifier, it may be redeclared in namespace scope with no initializer (this usage is -deprecated; see \ref{depr.static_constexpr}). Declarations of other +deprecated; see \ref{depr.static.constexpr}). Declarations of other static data members shall not specify a \grammarterm{brace-or-equal-initializer}. \pnum @@ -2846,7 +2851,8 @@ \pnum \begin{note} -Static data members of a class in namespace scope have the linkage of that class\iref{basic.link}. A local class cannot have static data members\iref{class.local}. +Static data members of a class in namespace scope have the linkage of the name of the class\iref{basic.link}. +A local class cannot have static data members\iref{class.local}. \end{note} \pnum @@ -2876,12 +2882,12 @@ A bit-field shall not be a static member. \indextext{bit-field!type of}% A bit-field shall have integral or enumeration type; -the bit-field attribute is not part of the type of the class member. +the bit-field semantic property is not part of the type of the class member. The \grammarterm{constant-expression} shall be an integral constant expression with a value greater than or equal to zero and is called the \defn{width} of the bit-field. If the width of a bit-field is larger than -the range exponent of the bit-field's type +the width of the bit-field's type (or, in case of an enumeration type, of its underlying type), the extra bits are padding bits\iref{basic.types}. \indextext{allocation!implementation-defined bit-field}% @@ -2933,7 +2939,7 @@ If a value of integral type (other than \tcode{bool}) is stored into a bit-field of width $N$ and the value would be representable in a hypothetical signed or unsigned integer type -with range exponent $N$ and the same signedness as the bit-field's type, +with width $N$ and the same signedness as the bit-field's type, the original value and the value of the bit-field compare equal. If the value \tcode{true} or \tcode{false} is stored into a bit-field of type \tcode{bool} of any size (including a one bit bit-field), the @@ -3226,7 +3232,7 @@ A union of the form \begin{ncsimplebnf} -\terminal{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} +\keyword{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} \end{ncsimplebnf} is called an \defn{anonymous union}; it defines an unnamed type and @@ -3412,14 +3418,14 @@ \begin{bnf} \nontermdef{base-specifier}\br \opt{attribute-specifier-seq} class-or-decltype\br - \opt{attribute-specifier-seq} \terminal{virtual} \opt{access-specifier} class-or-decltype\br - \opt{attribute-specifier-seq} access-specifier \opt{\terminal{virtual}} class-or-decltype + \opt{attribute-specifier-seq} \keyword{virtual} \opt{access-specifier} class-or-decltype\br + \opt{attribute-specifier-seq} access-specifier \opt{\keyword{virtual}} class-or-decltype \end{bnf} \begin{bnf} \nontermdef{class-or-decltype}\br \opt{nested-name-specifier} type-name\br - nested-name-specifier \terminal{template} simple-template-id\br + nested-name-specifier \keyword{template} simple-template-id\br decltype-specifier \end{bnf} @@ -3427,9 +3433,9 @@ % \begin{bnf} \nontermdef{access-specifier}\br - \terminal{private}\br - \terminal{protected}\br - \terminal{public} + \keyword{private}\br + \keyword{protected}\br + \keyword{public} \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{base-specifier}. @@ -5121,9 +5127,9 @@ shall have one of the following forms: \begin{ncsimplebnf} -\terminal{friend} elaborated-type-specifier \terminal{;}\br -\terminal{friend} simple-type-specifier \terminal{;}\br -\terminal{friend} typename-specifier \terminal{;} +\keyword{friend} elaborated-type-specifier \terminal{;}\br +\keyword{friend} simple-type-specifier \terminal{;}\br +\keyword{friend} typename-specifier \terminal{;} \end{ncsimplebnf} \begin{note} A friend declaration may be the @@ -6495,6 +6501,11 @@ operand to the exception object\iref{except.throw} can be omitted by constructing the automatic object directly into the exception object +\item in a coroutine\iref{dcl.fct.def.coroutine}, a copy of a coroutine parameter +can be omitted and references to that copy replaced with references to the +corresponding parameter if the meaning of the program will be unchanged except for +the execution of a constructor and destructor for the parameter copy object + \item when the \grammarterm{exception-declaration} of an exception handler\iref{except} declares an object of the same type (except for cv-qualification) as the exception @@ -6506,12 +6517,12 @@ \begin{note} There cannot be a move from the exception object because it is always an lvalue. \end{note} \end{itemize} -Copy elision is required +Copy elision is not permitted where an expression is evaluated in a context requiring a constant expression\iref{expr.const} and in constant initialization\iref{basic.start.static}. \begin{note} -Copy elision might not be performed +Copy elision might be performed if the same expression is evaluated in another context. \end{note} @@ -6572,7 +6583,7 @@ \pnum In the following copy-initialization contexts, a move operation might be used instead of a copy operation: \begin{itemize} -\item If the \grammarterm{expression} in a \tcode{return} statement\iref{stmt.return} +\item If the \grammarterm{expression} in a \tcode{return} or \tcode{co_return} statement\iref{stmt.return} is a (possibly parenthesized) \grammarterm{id-expression} that names an object with automatic storage duration declared in the body or \grammarterm{parameter-declaration-clause} of the innermost enclosing @@ -6585,16 +6596,20 @@ \grammarterm{try-block} (if there is one), \end{itemize} overload resolution to select the constructor -for the copy is first performed as if the object were designated by an +for the copy or the \tcode{return_value} overload to call +is first performed as if the object were designated by an rvalue. If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected -constructor is not an rvalue reference to the object's type (possibly cv-qualified), +constructor or the \tcode{return_value} overload +is not an rvalue reference to the object's type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. \begin{note} This two-stage overload resolution must be performed regardless -of whether copy elision will occur. It determines the constructor to be called if -elision is not performed, and the selected constructor must be accessible even if +of whether copy elision will occur. It determines the constructor +or the \tcode{return_value} overload to be called if +elision is not performed, and the selected constructor +or the \tcode{return_value} overload must be accessible even if the call is elided. \end{note} @@ -6642,28 +6657,56 @@ declared in the \grammarterm{member-specification} of \tcode{C} that is \begin{itemize} -\item a non-static member of \tcode{C} having one parameter of type \tcode{const C\&}, or +\item a non-static const member of \tcode{C} having one parameter of type \tcode{const C\&}, or \item a friend of \tcode{C} having two parameters of type \tcode{const C\&}. \end{itemize} \pnum -\indextext{structural comparison operator|see{operator, structural comparison}}% -A three-way comparison operator for a class type \tcode{C} -is a \defnadj{structural comparison}{operator} -if it is defined as defaulted in the definition of \tcode{C}, -and all three-way comparison operators it invokes -are structural comparison operators. -\indextext{strong structural equality|see{equality, strong structural}}% -A type \tcode{T} -has \defnadj{strong structural}{equality} -if, for a glvalue \tcode{x} of type \tcode{const T}, -\tcode{x <=> x} is a valid expression -of type \tcode{std::strong_ordering} or \tcode{std::strong_equality} -and either does not invoke a three-way comparison operator -or invokes a structural comparison operator. +If the class definition +does not explicitly declare an \tcode{==} operator function, +but declares a defaulted three-way comparison operator function, +an \tcode{==} operator function is declared implicitly +with the same access as the three-way comparison operator function. +The implicitly-declared \tcode{==} operator for a class \tcode{X} +is an inline member and is defined as defaulted in the definition of \tcode{X}. +If the three-way comparison operator function +is declared as a non-static const member, +the implicitly-declared \tcode{==} operator function is a member of the form +\begin{codeblock} +bool X::operator==(const X&) const; +\end{codeblock} +Otherwise, the implicitly-declared \tcode{==} operator function is of the form +\begin{codeblock} +friend bool operator==(const X&, const X&); +\end{codeblock} +\begin{note} +Such a friend function is visible +to argument-dependent lookup\iref{basic.lookup.argdep} +only\iref{namespace.memdef}. +\end{note} +The operator is a \tcode{constexpr} function if its definition +would satisfy the requirements for a \tcode{constexpr} function. +\begin{note} +The \tcode{==} operator function is declared implicitly even if +the defaulted three-way comparison operator function is defined as deleted. +\end{note} -\rSec2[class.spaceship]{Three-way comparison} -\indextext{operator!three-way comparison!defaulted}% +\pnum +\indextext{structural comparison operator|see{operator, structural comparison}}% +A type \tcode{C} has \defnadj{strong structural}{equality} if, +given a glvalue \tcode{x} of type \tcode{const C}, either: +\begin{itemize} +\item + \tcode{C} is a non-class type and \tcode{x <=> x} is a valid expression + of type \tcode{std::strong_ordering} or \tcode{std::strong_equality}, or +\item + \tcode{C} is a class type with an \tcode{==} operator + defined as defaulted in the definition of \tcode{C}, + \tcode{x == x} is well-formed when contextually converted to \tcode{bool}, + all of \tcode{C}'s base class subobjects and non-static data members + have strong structural equality, and + \tcode{C} has no \tcode{mutable} or \tcode{volatile} subobjects. +\end{itemize} \pnum The direct base class subobjects of \tcode{C}, @@ -6681,12 +6724,71 @@ derived-to-base conversions\iref{over.best.ics}, class member access expressions\iref{expr.ref}, and array subscript expressions\iref{expr.sub} applied to \tcode{x}. -The type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ -is denoted by $\tcode{R}_i$. -It is unspecified -whether virtual base class subobjects are compared more than once. +It is unspecified whether virtual base class subobjects +appear more than once in the expanded list of subobjects. + +\rSec2[class.eq]{Equality operators} +\indextext{operator!equality!defaulted}% +\indextext{operator!inequality!defaulted}% + +\pnum +A defaulted equality operator\iref{expr.eq} function +shall have a declared return type \tcode{bool}. + +\pnum +A defaulted \tcode{==} operator function for a class \tcode{C} +is defined as deleted +unless, for each $\tcode{x}_i$ in the expanded list of subobjects +for an object \tcode{x} of type \tcode{C}, +$\tcode{x}_i\tcode{ == }\tcode{x}_i$ is a valid expression and +contextually convertible to \tcode{bool}. + +\pnum +The return value \tcode{V} of a defaulted \tcode{==} operator function +with parameters \tcode{x} and \tcode{y} is determined +by comparing corresponding elements $\tcode{x}_i$ and $\tcode{y}_i$ +in the expanded lists of subobjects for \tcode{x} and \tcode{y} +(in increasing index order) +until the first index $i$ +where $\tcode{x}_i\tcode{ == }\tcode{y}_i$ yields a result value which, +when contextually converted to \tcode{bool}, yields \tcode{false}. +If no such index exists, \tcode{V} is \tcode{true}. +Otherwise, \tcode{V} is \tcode{false}. + +\pnum +A defaulted \tcode{!=} operator function for a class \tcode{C} +with parameters \tcode{x} and \tcode{y} is defined as deleted if +\begin{itemize} +\item + overload resolution\iref{over.match}, as applied to \tcode{x == y} + (also considering synthesized candidates + with reversed order of parameters\iref{over.match.oper}), + results in an ambiguity or a function + that is deleted or inaccessible from the operator function, or +\item + \tcode{x == y} cannot be contextually converted to \tcode{bool}. +\end{itemize} +Otherwise, the operator function yields \tcode{(x == y) ?\ false :\ true}. + +\pnum +\begin{example} +\begin{codeblock} +struct D { + int i; + friend bool operator==(const D& x, const D& y) = default; + // OK, returns \tcode{x.i == y.i} + bool operator!=(const D& z) const = default; // OK, returns \tcode{(*this == z) ?\ false :\ true} +}; +\end{codeblock} +\end{example} + +\rSec2[class.spaceship]{Three-way comparison} +\indextext{operator!three-way comparison!defaulted}% \pnum +Given an expanded list of subobjects for an object \tcode{x} of type \tcode{C}, +the type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ +is denoted by $\tcode{R}_i$. If the declared return type of a defaulted three-way comparison operator function is \tcode{auto}, @@ -6709,6 +6811,7 @@ is determined by comparing corresponding elements $\tcode{x}_i$ and $\tcode{y}_i$ in the expanded lists of subobjects for \tcode{x} and \tcode{y} +(in increasing index order) until the first index $i$ where $\tcode{x}_i$ \tcode{<=>} $\tcode{y}_i$ yields a result value $\tcode{v}_i$ where $\tcode{v}_i \mathrel{\tcode{!=}} 0$, @@ -6756,13 +6859,11 @@ \end{note} \end{itemize} -\rSec2[class.rel.eq]{Other comparison operators} +\rSec2[class.rel]{Relational operators} \indextext{operator!relational!defaulted}% -\indextext{operator!equality!defaulted}% -\indextext{operator!inequality!defaulted}% \pnum -A defaulted relational\iref{expr.rel} or equality\iref{expr.eq} operator function +A defaulted relational\iref{expr.rel} operator function for some operator \tcode{@} shall have a declared return type \tcode{bool}. @@ -6774,29 +6875,23 @@ \item overload resolution\iref{over.match}, as applied to \tcode{x <=> y} -(also considering synthesized candidates with reversed order of parameters\iref{over.match.oper}), results in an ambiguity or a function that is deleted or inaccessible from the operator function, or \item the operator \tcode{@} -cannot be applied to the return type of \tcode{x <=> y} or \tcode{y <=> x}. +cannot be applied to the return type of \tcode{x <=> y}. \end{itemize} Otherwise, the operator function yields -\tcode{x <=> y @ 0} -if an \tcode{operator<=>} -with the original order of parameters was selected, or -\tcode{0 @ y <=> x} -otherwise. +\tcode{x <=> y @ 0}. \pnum \begin{example} \begin{codeblock} struct C { friend std::strong_equality operator<=>(const C&, const C&); - friend bool operator==(const C&, const C&) = default; // OK, returns \tcode{x <=> y == 0} bool operator<(const C&) const = default; // OK, function is deleted }; \end{codeblock} diff --git a/source/compatibility.tex b/source/compatibility.tex index 68745cc68e..33e70c15ed 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -67,10 +67,10 @@ The type of a UTF-8 string literal is changed from ``array of \tcode{char}'' to ``array of \tcode{const char8_t}''. -The type of a \tcode{char16_t} string literal is changed +The type of a UTF-16 string literal is changed from ``array of \textit{some-integer-type}'' to ``array of \tcode{const char16_t}''. -The type of a \tcode{char32_t} string literal is changed +The type of a UTF-32 string literal is changed from ``array of \textit{some-integer-type}'' to ``array of \tcode{const char32_t}''. The type of a wide string literal is changed @@ -1791,6 +1791,20 @@ \rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions} +\diffref{lex.header} +\change \grammarterm{header-name} tokens are formed in more contexts. +\rationale Required for new features. +\effect When the identifier \tcode{import} +is followed by a \tcode{<} character, +a \grammarterm{header-name} token may be formed. +\begin{example} +\begin{codeblock} +template class import {}; +import f(); // ill-formed; previously well-formed +::import g(); // OK +\end{codeblock} +\end{example} + \diffref{lex.key} \change New keywords. \rationale Required for new features. @@ -1805,6 +1819,9 @@ The \tcode{consteval} keyword is added to declare immediate functions\iref{dcl.constexpr}. \item +The \tcode{co_await}, \tcode{co_yield}, and \tcode{co_return} keywords are added +to enable the definition of coroutines \iref{dcl.fct.def.coroutine}. +\item The \tcode{requires} keyword is added to introduce constraints through a \grammarterm{requires-clause} or a \grammarterm{requires-expression}. @@ -1814,6 +1831,7 @@ \tcode{char8_t}, \tcode{concept}, \tcode{consteval}, +\tcode{co_await}, \tcode{co_yield}, \tcode{co_return}, or \tcode{requires} as an identifier is not valid in this International Standard. @@ -1862,6 +1880,25 @@ \rSec2[diff.cpp17.basic]{\ref{basic}: basics} +\diffref{basic.link,module.unit,module.import} +\change New identifiers with special meaning. +\rationale Required for new features. +\effect Top-level declarations beginning with +\tcode{module} or \tcode{import} may +be either ill-formed or interpreted differently +in this International Standard. +\begin{example} +\begin{codeblock} +class module; +module *m1; // ill-formed; previously well-formed +::module *m2; // OK + +class import {}; +import j1; // was variable declaration; now \grammarterm{import-declaration} +::import j2; // variable declaration +\end{codeblock} +\end{example} + \diffref{intro.races} \change Except for the initial release operation, a release sequence consists solely of atomic read-modify-write operations. @@ -2029,6 +2066,7 @@ \tcode{}, \tcode{}, \tcode{}, +\tcode{}, \tcode{}, \tcode{}, \tcode{}, and diff --git a/source/concepts.tex b/source/concepts.tex index 6eea186a18..18763fc951 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -15,6 +15,7 @@ \tref{concepts.lib.summary}. \begin{libsumtab}{Fundamental concepts library summary}{tab:concepts.lib.summary} +\ref{concepts.equality} & Equality preservation & \\ \hline \ref{concepts.lang} & Language-related concepts & \tcode{} \\ \ref{concepts.compare} & Comparison concepts & \\ \ref{concepts.object} & Object concepts & \\ @@ -272,13 +273,18 @@ \indexlibrary{\idxcode{Same}}% \begin{itemdecl} template - concept Same = is_same_v; + concept @\placeholdernc{same-impl}@ = is_same_v; // \expos + +template + concept Same = @\placeholdernc{same-impl}@ && @\placeholdernc{same-impl}@; \end{itemdecl} \begin{itemdescr} \pnum +\begin{note} \tcode{\libconcept{Same}} subsumes \tcode{\libconcept{Same}} and vice versa. +\end{note} \end{itemdescr} \rSec2[concept.derivedfrom]{Concept \libconcept{DerivedFrom}} diff --git a/source/config.tex b/source/config.tex index 5fa1de17ed..54017e5254 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4800} -\newcommand{\prevdocno}{N4791} +\newcommand{\docno}{N4810} +\newcommand{\prevdocno}{N4800} \newcommand{\cppver}{201703L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index 79ed5d63c1..bfceedb1e9 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -98,7 +98,7 @@ \tcode{X::value_type} & \tcode{T} & & - \requires\ \tcode{T} is \oldconcept{Erasable} from \tcode{X} (see~\ref{container.requirements.general}, below) & + \expects \tcode{T} is \oldconcept{Erasable} from \tcode{X} (see~\ref{container.requirements.general}, below) & compile time \\ \rowsep \tcode{X::reference} & @@ -155,7 +155,7 @@ \tcode{X(a)} & & & - \requires \tcode{T} is \oldconcept{CopyInsertable} + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below).\br \ensures \tcode{a == X(a)}. & linear \\ \rowsep @@ -163,7 +163,7 @@ \tcode{X u = a;} & & & - \requires \tcode{T} is \oldconcept{CopyInsertable} + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below).\br \ensures \tcode{u == a} & linear \\ \rowsep @@ -172,21 +172,21 @@ \tcode{X u = rv;} & & & - \ensures \tcode{u} shall be equal to the value that \tcode{rv} had before this construction + \ensures \tcode{u} is equal to the value that \tcode{rv} had before this construction & (Note B) \\ \rowsep \tcode{a = rv} & \tcode{X\&} & All existing elements of \tcode{a} are either move assigned to or destroyed & - \tcode{a} shall be equal to the value that \tcode{rv} + \ensures \tcode{a} is equal to the value that \tcode{rv} had before this assignment & linear \\ \rowsep \tcode{a.\~X()} & \tcode{void} & & - the destructor is applied to every element of \tcode{a}; any memory obtained is deallocated. & + \effects destroys every element of \tcode{a}; any memory obtained is deallocated. & linear \\ \rowsep \tcode{a.begin()} & @@ -217,7 +217,7 @@ convertible to \tcode{bool} & \tcode{==} is an equivalence relation. \tcode{equal(\brk{}a.begin(), a.end(), b.begin(), b.end())} & - \requires\ \tcode{T} is \oldconcept{\-Equal\-ity\-Compar\-a\-ble} & + \expects \tcode{T} meets the \oldconcept{\-Equal\-ity\-Compar\-a\-ble} requirements & Constant if \tcode{a.size() != b.size()}, linear otherwise \\ \rowsep @@ -230,7 +230,7 @@ \tcode{a.swap(b)} & \tcode{void} & & - exchanges the contents of \tcode{a} and \tcode{b} & + \effects exchanges the contents of \tcode{a} and \tcode{b} & (Note A) \\ \rowsep \tcode{swap(a, b)} & @@ -488,7 +488,7 @@ \tcode{a < b} & convertible to \tcode{bool} & \tcode{lexicographical_compare( a.begin(), a.end(), b.begin(), b.end())} & - \requires \tcode{<} is defined for values of \tcode{T}. \tcode{<} is a total ordering relationship. & + \expects \tcode{<} is defined for values of type (possibly \tcode{const}) \tcode{T}. \tcode{<} is a total ordering relationship. & linear \\ \rowsep \tcode{a > b} & @@ -627,7 +627,7 @@ \tcode{allocator_type} & \tcode{A} & - \requires \tcode{allocator_type::value_type} is the same as \tcode{X::value_type}. & + \mandates \tcode{allocator_type::value_type} is the same as \tcode{X::value_type}. & compile time \\ \rowsep \tcode{get_-} \tcode{allocator()} & @@ -638,7 +638,7 @@ \tcode{X()}\br \tcode{X u;} & & - \requires\ \tcode{A} is \oldconcept{DefaultConstructible}.\br + \expects \tcode{A} meets the \oldconcept{DefaultConstructible} requirements.\br \ensures \tcode{u.empty()} returns \tcode{true}, \tcode{u.get_allocator() == A()} & constant \\ \rowsep @@ -655,7 +655,7 @@ \tcode{X(t, m)}\br \tcode{X u(t, m);} & & -\requires\ \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}.\br +\expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}.\br \ensures \tcode{u == t}, \tcode{u.get_allocator() == m} & linear \\ \rowsep @@ -663,24 +663,24 @@ \tcode{X u(rv);} & & - \ensures \tcode{u} shall have the same elements as \tcode{rv} had before this - construction; the value of \tcode{u.get_allocator()} shall be the same as the + \ensures \tcode{u} has the same elements as \tcode{rv} had before this + construction; the value of \tcode{u.get_allocator()} is the same as the value of \tcode{rv.get_allocator()} before this construction. & constant \\ \rowsep \tcode{X(rv, m)}\br \tcode{X u(rv, m);} & & - \requires\ \tcode{T} is + \expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}.\br - \ensures \tcode{u} shall have the same elements, + \ensures \tcode{u} has the same elements, or copies of the elements, that \tcode{rv} had before this construction, \tcode{u.get_allocator() == m} & constant if \tcode{m ==} \tcode{rv.get_allocator()}, otherwise linear \\ \rowsep \tcode{a = t} & \tcode{X\&} & - \requires\ \tcode{T} is + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} and \oldconcept{CopyAssignable}.\br \ensures \tcode{a == t} & @@ -688,21 +688,22 @@ \tcode{a = rv} & \tcode{X\&} & - \requires\ If \tcode{allocator_-}\br + \expects If \tcode{allocator_-}\br \tcode{traits}\br \tcode{::propagate_on_container_-}\br \tcode{move_assignment::value} is\br \tcode{false}, \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X} and - \oldconcept{MoveAssignable}. All existing elements of \tcode{a} + \oldconcept{MoveAssignable}.\br + \effects All existing elements of \tcode{a} are either move assigned to or destroyed.\br - \ensures \tcode{a} shall be equal to the value that \tcode{rv} had before + \ensures \tcode{a} is equal to the value that \tcode{rv} had before this assignment. & linear \\ \rowsep \tcode{a.swap(b)} & \tcode{void} & - exchanges the contents of \tcode{a} and \tcode{b} & + \effects exchanges the contents of \tcode{a} and \tcode{b} & constant \\ \rowsep \end{libreqtab4a} @@ -828,23 +829,23 @@ \tcode{X(n, t)}\br \tcode{X u(n, t);} & & - \requires\ \tcode{T} shall be + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}.\br \ensures \tcode{distance(begin(), end()) == n}\br - Constructs a sequence container with \tcode{n} copies of \tcode{t} \\ \rowsep + \effects Constructs a sequence container with \tcode{n} copies of \tcode{t} \\ \rowsep \tcode{X(i, j)}\br \tcode{X u(i, j);} & & - \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. For \tcode{vector}, if the iterator does not meet the \oldconcept{\-Forward\-Iterator} requirements\iref{forward.iterators}, \tcode{T} - shall also be - \oldconcept{MoveInsertable} into \tcode{X}. - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br + is also + \oldconcept{MoveInsertable} into \tcode{X}.\br \ensures \tcode{distance(begin(), end()) ==} \tcode{distance(i, j)}\br - Constructs a sequence container equal to the range \tcode{[i, j)} \\ \rowsep + \effects Constructs a sequence container equal to the range \tcode{[i, j)}. + Each iterator in the range \range{i}{j} is dereferenced exactly once. \\ \rowsep \tcode{X(il)} & & @@ -852,20 +853,20 @@ \tcode{a = il} & \tcode{X\&} & - \requires\ \tcode{T} is + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} - and \oldconcept{CopyAssignable}. - Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing + and \oldconcept{CopyAssignable}.\br + \effects Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing elements of \tcode{a} are either assigned to or destroyed.\br \returns\ \tcode{*this}. \\ \rowsep \tcode{a.emplace(p, args)} & \tcode{iterator} & - \requires\ \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector} and \tcode{deque}, + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector} and \tcode{deque}, \tcode{T} is also - \oldconcept{MoveInsertable} into \tcode{X} and \oldconcept{MoveAssignable}. - \effects\ Inserts an object of type \tcode{T} constructed with + \oldconcept{MoveInsertable} into \tcode{X} and \oldconcept{MoveAssignable}.\br + \effects Inserts an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} before \tcode{p}. \begin{note} \tcode{args} may directly or indirectly refer to a value in \tcode{a}. \end{note} @@ -873,34 +874,34 @@ \tcode{a.insert(p,t)} & \tcode{iterator} & - \requires\ \tcode{T} shall be + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \oldconcept{CopyAssignable}.\br + \tcode{T} is also \oldconcept{CopyAssignable}.\br \effects\ Inserts a copy of \tcode{t} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,rv)} & \tcode{iterator} & - \requires\ \tcode{T} shall be + \expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \oldconcept{MoveAssignable}.\br + \tcode{T} is also \oldconcept{MoveAssignable}.\br \effects\ Inserts a copy of \tcode{rv} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,n,t)} & \tcode{iterator} & - \requires\ \tcode{T} shall be + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} and \oldconcept{CopyAssignable}.\br - Inserts \tcode{n} copies of \tcode{t} before \tcode{p}. \\ \rowsep + \effects Inserts \tcode{n} copies of \tcode{t} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,i,j)} & \tcode{iterator} & - \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. - For \tcode{vector} and \tcode{deque}, \tcode{T} shall also be + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + For \tcode{vector} and \tcode{deque}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}, \oldconcept{MoveConstructible}, \oldconcept{MoveAssignable}, and swappable\iref{swappable.requirements}. - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - \requires \tcode{i} and \tcode{j} are not iterators into \tcode{a}.\br - Inserts copies of elements in \tcode{[i, j)} before \tcode{p} \\ \rowsep + Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}.\br + \effects Inserts copies of elements in \tcode{[i, j)} before \tcode{p}. + Each iterator in the range \range{i}{j} shall be dereferenced exactly once. \\ \rowsep \tcode{a.insert(p, il)} & \tcode{iterator} & @@ -908,37 +909,38 @@ \tcode{a.erase(q)} & \tcode{iterator} & - \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \oldconcept{MoveAssignable}.\br + \expects For \tcode{vector} and \tcode{deque}, + \tcode{T} is \oldconcept{MoveAssignable}.\br \effects\ Erases the element pointed to by \tcode{q}. \\ \rowsep \tcode{a.erase(q1,q2)} & \tcode{iterator} & - \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \oldconcept{MoveAssignable}.\br + \expects For \tcode{vector} and \tcode{deque}, + \tcode{T} is \oldconcept{MoveAssignable}.\br \effects\ Erases the elements in the range \tcode{[q1, q2)}. \\ \rowsep \tcode{a.clear()} & \tcode{void} & - Destroys all elements in \tcode{a}. Invalidates all references, pointers, and + \effects Destroys all elements in \tcode{a}. Invalidates all references, pointers, and iterators referring to the elements of \tcode{a} and may invalidate the past-the-end iterator.\br - \ensures \tcode{a.empty()} returns \tcode{true}.\br + \ensures \tcode{a.empty()} is \tcode{true}.\br \complexity Linear. \\ \rowsep \tcode{a.assign(i,j)} & \tcode{void} & - \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i} + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i} and assignable from \tcode{*i}. For \tcode{vector}, if the iterator does not meet the forward iterator requirements\iref{forward.iterators}, \tcode{T} - shall also be - \oldconcept{MoveInsertable} into \tcode{X}.\br - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - \requires \tcode{i}, \tcode{j} are not iterators into \tcode{a}.\br - Replaces elements in \tcode{a} with a copy of \tcode{[i, j)}.\br + is also + \oldconcept{MoveInsertable} into \tcode{X}. + Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}.\br + \effects + Replaces elements in \tcode{a} with a copy of \tcode{[i, j)}. Invalidates all references, pointers and iterators referring to the elements of \tcode{a}. For \tcode{vector} and \tcode{deque}, - also invalidates the past-the-end iterator. \\ \rowsep + also invalidates the past-the-end iterator. + Each iterator in the range \range{i}{j} shall be dereferenced exactly once. \\ \rowsep \tcode{a.assign(il)} & \tcode{void} & @@ -946,11 +948,11 @@ \tcode{a.assign(n,t)} & \tcode{void} & - \requires\ \tcode{T} shall be + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} - and \oldconcept{CopyAssignable}.\br - \requires \tcode{t} is not a reference into \tcode{a}.\br - Replaces elements in \tcode{a} with \tcode{n} copies of \tcode{t}.\br + and \oldconcept{CopyAssignable}. + \tcode{t} is not a reference into \tcode{a}.\br + \effects Replaces elements in \tcode{a} with \tcode{n} copies of \tcode{t}. Invalidates all references, pointers and iterators referring to the elements of \tcode{a}. For \tcode{vector} and \tcode{deque}, @@ -1087,9 +1089,9 @@ \tcode{a.emplace_\-front(args)} & \tcode{reference} & - Prepends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br - \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \returns{} \tcode{a.front()}. & + \effects Prepends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \returns \tcode{a.front()}. & \tcode{deque}, \tcode{forward_list}, \tcode{list} @@ -1097,11 +1099,11 @@ \tcode{a.emplace_\-back(args)} & \tcode{reference} & - Appends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br - \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} - shall also be + \effects Appends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br + \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} + is also \oldconcept{MoveInsertable} into \tcode{X}.\br - \returns{} \tcode{a.back()}. & + \returns \tcode{a.back()}. & \tcode{deque}, \tcode{list}, \tcode{vector} @@ -1109,8 +1111,8 @@ \tcode{a.push_front(t)} & \tcode{void} & - Prepends a copy of \tcode{t}.\br - \requires\ \tcode{T} shall be + \effects Prepends a copy of \tcode{t}.\br + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. & \tcode{deque}, @@ -1120,8 +1122,8 @@ \tcode{a.push_front(rv)} & \tcode{void} & - Prepends a copy of \tcode{rv}.\br - \requires\ \tcode{T} shall be + \effects Prepends a copy of \tcode{rv}.\br + \expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. & \tcode{deque}, @@ -1131,8 +1133,8 @@ \tcode{a.push_back(t)} & \tcode{void} & - Appends a copy of \tcode{t}.\br - \requires\ \tcode{T} shall be + \effects Appends a copy of \tcode{t}.\br + \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. & \tcode{basic_string}, @@ -1143,8 +1145,8 @@ \tcode{a.push_back(rv)} & \tcode{void} & - Appends a copy of \tcode{rv}.\br - \requires\ \tcode{T} shall be + \effects Appends a copy of \tcode{rv}.\br + \expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. & \tcode{basic_string}, @@ -1155,8 +1157,8 @@ \tcode{a.pop_front()} & \tcode{void} & - Destroys the first element.\br - \requires\ \tcode{a.empty()} shall be \tcode{false}. & + \effects Destroys the first element.\br + \expects \tcode{a.empty()} is \tcode{false}. & \tcode{deque}, \tcode{forward_list}, \tcode{list} @@ -1164,8 +1166,8 @@ \tcode{a.pop_back()} & \tcode{void} & - Destroys the last element.\br - \requires\ \tcode{a.empty()} shall be \tcode{false}. & + \effects Destroys the last element.\br + \expects \tcode{a.empty()} is \tcode{false}. & \tcode{basic_string}, \tcode{deque}, \tcode{list}, @@ -1265,7 +1267,7 @@ using container_node_type = @\unspecnc@; using ator_traits = allocator_traits; - typename ator_traits::rebind_traits::pointer ptr_; + typename ator_traits::template rebind_traits::pointer ptr_; optional alloc_; public: @@ -1317,8 +1319,8 @@ \begin{itemdescr} \pnum -\requires Either \tcode{!alloc_}, or -\tcode{ator_traits::propagate_on_container_move_assignment} +\expects Either \tcode{!alloc_}, or +\tcode{ator_traits::propagate_on_container_move_assignment::value} is \tcode{true}, or \tcode{alloc_ == nh.alloc_}. \pnum @@ -1328,12 +1330,13 @@ If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} subobject in the \tcode{container_node_type} object pointed to by \tcode{ptr_} by calling \tcode{ator_traits::destroy}, then deallocates \tcode{ptr_} by -calling \tcode{ator_traits::rebind_traits::deallocate}. +calling \tcode{ator_traits::template rebind_traits::deallocate}. \item Assigns \tcode{nh.ptr_} to \tcode{ptr_}. \item -If \tcode{!alloc\textunderscore} or \tcode{ator_traits::propagate_on_container_move_assignment} -is \tcode{true}, move assigns \tcode{nh.alloc_} to \tcode{alloc_}. +If \tcode{!alloc\textunderscore} or \tcode{ator_traits::propagate_on_container_move_assignment::value} +is \tcode{true}, \linebreak +move assigns \tcode{nh.alloc_} to \tcode{alloc_}. \item Assigns \tcode{nullptr} to \tcode{nh.ptr_} and assigns \tcode{nullopt} to @@ -1356,7 +1359,7 @@ \effects If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} subobject in the \tcode{container_node_type} object pointed to by \tcode{ptr_} by calling \tcode{ator_traits::destroy}, then deallocates \tcode{ptr_} by calling -\tcode{ator_traits::rebind_traits::deallocate}. +\tcode{ator_traits::template rebind_traits::deallocate}. \end{itemdescr} \rSec3[container.node.observers]{Observers} @@ -1367,7 +1370,7 @@ \begin{itemdescr} \pnum -\requires \tcode{empty() == false}. +\expects \tcode{empty() == false}. \pnum \returns A reference to the \tcode{value_type} subobject in the @@ -1383,7 +1386,7 @@ \begin{itemdescr} \pnum -\requires \tcode{empty() == false}. +\expects \tcode{empty() == false}. \pnum \returns A non-const reference to the \tcode{key_type} member of the @@ -1403,7 +1406,7 @@ \begin{itemdescr} \pnum -\requires \tcode{empty() == false}. +\expects \tcode{empty() == false}. \pnum \returns A reference to the \tcode{mapped_type} member of the @@ -1421,7 +1424,7 @@ \begin{itemdescr} \pnum -\requires \tcode{empty() == false}. +\expects \tcode{empty() == false}. \pnum \returns \tcode{*alloc_}. @@ -1458,13 +1461,13 @@ \begin{itemdescr} \pnum -\requires \tcode{!alloc_}, or \tcode{!nh.alloc_}, or -\tcode{ator_traits::propagate_on_container_swap} is \tcode{true}, +\expects \tcode{!alloc_}, or \tcode{!nh.alloc_}, or +\tcode{ator_traits::propagate_on_container_swap::value} is \tcode{true}, or \tcode{alloc_ == nh.alloc_}. \pnum \effects Calls \tcode{swap(ptr_, nh.ptr_)}. If \tcode{!alloc_}, or -\tcode{!nh.alloc_}, or \tcode{ator_traits::propagate_on_container_swap} +\tcode{!nh.alloc_}, or \tcode{ator_traits::propagate_on_container_swap::value} is \tcode{true} calls \tcode{swap(alloc_, nh.alloc_)}. \end{itemdescr} @@ -1661,18 +1664,18 @@ \indexordmem{value_type}% \tcode{X::value_type} (\tcode{set} and \tcode{multiset} only) & \tcode{Key} & - \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & + \expects \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \tcode{X::value_type} (\tcode{map} and \tcode{multimap} only) & \tcode{pair} & - \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & + \expects \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \indexordmem{key_compare}% \tcode{X::key_compare} & \tcode{Compare} & - \requires\ \tcode{key_compare} is \oldconcept{CopyConstructible}. & + \expects \tcode{key_compare} is \oldconcept{CopyConstructible}. & compile time \\ \rowsep \indexordmem{value_compare}% @@ -1704,7 +1707,7 @@ \tcode{X()}\br\tcode{X u;} & & - \requires\ \tcode{key_compare} is \oldconcept{DefaultConstructible}.\br + \expects \tcode{key_compare} meets the \oldconcept{DefaultConstructible} requirements.\br \effects\ Constructs an empty container. Uses \tcode{Compare()} as a comparison object & constant \\ \rowsep @@ -1712,7 +1715,7 @@ \tcode{X(i,j,c)}\br \tcode{X~u(i,j,c);} & & - \requires\ \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container and inserts elements from the range \tcode{[i, j)} into it; uses \tcode{c} as a comparison object. & $N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; @@ -1720,7 +1723,7 @@ \tcode{X(i,j)}\br\tcode{X~u(i,j);} & & - \requires\ \tcode{key_compare} is \oldconcept{DefaultConstructible}. + \expects \tcode{key_compare} meets the \oldconcept{DefaultConstructible} requirements. \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Same as above, but uses \tcode{Compare()} as a comparison object. & same as above \\ \rowsep @@ -1737,7 +1740,7 @@ \tcode{a = il} & \tcode{X\&} & - \requires\ \tcode{value_type} is + \expects \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X} and \oldconcept{CopyAssignable}.\br \effects Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All @@ -1749,19 +1752,19 @@ \indexordmem{key_comp}% \tcode{b.key_comp()} & \tcode{X::key_compare} & - returns the comparison object out of which \tcode{b} was constructed. & + \returns the comparison object out of which \tcode{b} was constructed. & constant \\ \rowsep \indexordmem{value_comp}% \tcode{b.value_comp()} & \tcode{X::value_compare} & - returns an object of \tcode{value_compare} constructed out of the comparison object & + \returns an object of \tcode{value_compare} constructed out of the comparison object & constant \\ \rowsep \indexordmem{emplace}% \tcode{a_uniq.\brk{}emplace(\brk{}args)} & \tcode{pair<\brk{}iterator, bool>} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. @@ -1773,7 +1776,7 @@ \tcode{a_eq.\brk{}emplace(\brk{}args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. @@ -1795,8 +1798,8 @@ \indexordmem{insert}% \tcode{a_uniq.\brk{}insert(\brk{}t)} & \tcode{pair<\brk{}iterator, bool>} & - \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} component of @@ -1808,8 +1811,8 @@ \tcode{a_eq.\brk{}insert(\brk{}t)} & \tcode{iterator} & - \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} and returns the iterator pointing to the newly inserted element. @@ -1820,8 +1823,8 @@ \tcode{a.\brk{}insert(\brk{}p, t)} & \tcode{iterator} & - \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element with key equivalent to the key of \tcode{t} in containers with unique keys; @@ -1834,9 +1837,9 @@ \tcode{a.\brk{}insert(\brk{}i, j)} & \tcode{void} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \requires \tcode{i}, \tcode{j} are not iterators into \tcode{a}. - inserts each element from the range \range{i}{j} if and only if there + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}.\br + \effects Inserts each element from the range \range{i}{j} if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys. & $N \log (\tcode{a.size()} + N)$, where $N$ has the value \tcode{distance(i, j)} \\ \rowsep @@ -1848,9 +1851,9 @@ \tcode{a_uniq.\brk{}insert(\brk{}nh)} & \tcode{insert_return_type} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a_uniq.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect. Otherwise, inserts the + \effects If \tcode{nh} is empty, has no effect. Otherwise, inserts the element owned by \tcode{nh} if and only if there is no element in the container with a key equivalent to \tcode{nh.key()}.\br \ensures If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, @@ -1864,9 +1867,9 @@ \tcode{a_eq.\brk{}insert(\brk{}nh)} & \tcode{iterator} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a_eq.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. + \effects If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. Otherwise, inserts the element owned by \tcode{nh} and returns an iterator pointing to the newly inserted element. If a range containing elements with keys equivalent to \tcode{nh.key()} exists in \tcode{a_eq}, the element is @@ -1876,9 +1879,9 @@ \tcode{a.\brk{}insert(\brk{}p, nh)} & \tcode{iterator} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. + \effects If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. Otherwise, inserts the element owned by \tcode{nh} if and only if there is no element with key equivalent to \tcode{nh.key()} in containers with unique keys; always inserts the element owned by \tcode{nh} in containers @@ -1892,22 +1895,22 @@ \indexordmem{extract}% \tcode{a.\brk{}extract(\brk{}k)} & \tcode{node_type} & - removes the first element in the container with key equivalent to \tcode{k}. - Returns a \tcode{node_type} owning the element if found, otherwise an empty + \effects Removes the first element in the container with key equivalent to \tcode{k}.\br + \returns A \tcode{node_type} owning the element if found, otherwise an empty \tcode{node_type}. & $\log (\tcode{a.size()})$ \\ \rowsep \tcode{a.\brk{}extract(\brk{}q)} & \tcode{node_type} & - removes the element pointed to by \tcode{q}. - Returns a \tcode{node_type} owning that element. & + \effects Removes the element pointed to by \tcode{q}.\br + \returns A \tcode{node_type} owning that element. & amortized constant \\ \rowsep \indexordmem{merge}% \tcode{a.merge(a2)} & \tcode{void} & - \requires \tcode{a.get_allocator() == a2.get_allocator()}.\br - Attempts to extract each element in \tcode{a2} and insert it into \tcode{a} + \expects \tcode{a.get_allocator() == a2.get_allocator()}.\br + \effects Attempts to extract each element in \tcode{a2} and insert it into \tcode{a} using the comparison object of \tcode{a}. In containers with unique keys, if there is an element in \tcode{a} with key equivalent to the key of an element from \tcode{a2}, then that element is not extracted from \tcode{a2}.\br @@ -1915,26 +1918,29 @@ refer to those same elements but as members of \tcode{a}. Iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators into \tcode{a}, not into \tcode{a2}.\br - \throws{} Nothing unless the comparison object throws. & + \throws Nothing unless the comparison object throws. & $N \log(\tcode{a.size()+} N)$, where $N$ has the value \tcode{a2.size()}. \\ \rowsep \indexordmem{erase}% \tcode{a.erase(k)} & \tcode{size_type} & - erases all elements in the container with key equivalent to - \tcode{k}. returns the number of erased elements. & + \effects Erases all elements in the container with key equivalent to + \tcode{k}.\br + \returns The number of erased elements. & $\log (\tcode{a.size()}) + \tcode{a.count(k)}$ \\ \rowsep \tcode{a.erase(q)} & \tcode{iterator} & - erases the element pointed to by \tcode{q}. Returns an iterator pointing to + \effects Erases the element pointed to by \tcode{q}.\br + \returns An iterator pointing to the element immediately following \tcode{q} prior to the element being erased. If no such element exists, returns \tcode{a.end()}. & amortized constant \\ \rowsep \tcode{a.erase(r)} & \tcode{iterator} & - erases the element pointed to by \tcode{r}. Returns an iterator pointing to + \effects Erases the element pointed to by \tcode{r}.\br + \returns An iterator pointing to the element immediately following \tcode{r} prior to the element being erased. If no such element exists, returns \tcode{a.end()}. & amortized constant \\ \rowsep @@ -1942,7 +1948,8 @@ \tcode{a.erase(}\br \tcode{q1, q2)} & \tcode{iterator} & - erases all the elements in the range \range{q1}{q2}. Returns an iterator pointing to + \effects Erases all the elements in the range \range{q1}{q2}.\br + \returns An iterator pointing to the element pointed to by \tcode{q2} prior to any elements being erased. If no such element exists, \tcode{a.end()} is returned. & $\log(\tcode{a.size()}) + N$, where $N$ has the value \tcode{distance(q1, q2)}. \\ \rowsep @@ -1950,35 +1957,35 @@ \indexordmem{clear}% \tcode{a.clear()} & \tcode{void} & - \tcode{a.erase(a.begin(),a.end())}\br - \ensures \tcode{a.empty()} returns \tcode{true}. & + \effects Equivalent to \tcode{a.erase(a.begin(), a.end())}.\br + \ensures \tcode{a.empty()} is \tcode{true}. & linear in \tcode{a.size()}. \\ \rowsep \indexordmem{find}% \tcode{b.find(k)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. & - returns an iterator pointing to an element with the key equivalent - to \tcode{k}, or \tcode{b.end()} if such an element is not found & + \returns An iterator pointing to an element with the key equivalent + to \tcode{k}, or \tcode{b.end()} if such an element is not found. & logarithmic \\ \rowsep \tcode{a_tran.}\br \tcode{find(ke)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to an element with key \tcode{r} such that + \returns An iterator pointing to an element with key \tcode{r} such that \tcode{!c(r, ke) \&\& !c(ke, r)}, or \tcode{a_tran.end()} if such an element - is not found & + is not found. & logarithmic \\ \rowsep \indexordmem{count}% \tcode{b.count(k)} & \tcode{size_type} & - returns the number of elements with key equivalent to \tcode{k} & + \returns The number of elements with key equivalent to \tcode{k}. & $\log (\tcode{b.size()}) + \tcode{b.count(k)}$ \\ \rowsep \tcode{a_tran.}\br \tcode{count(ke)} & \tcode{size_type} & - returns the number of elements with key \tcode{r} such that + \returns The number of elements with key \tcode{r} such that \tcode{!c(r, ke) \&\& !c(ke, r)} & $\log (\tcode{a_tran.size()}) + \tcode{a_tran.count(ke)}$ \\ \rowsep @@ -1986,19 +1993,19 @@ \tcode{b.}\br \tcode{contains(k)} & \tcode{bool} & - equivalent to \tcode{b.find(k) != b.end()} & + \effects Equivalent to: \tcode{return b.find(k) != b.end();} & logarithmic \\ \rowsep \tcode{a_tran.}\br \tcode{con\-tains(ke)} & \tcode{bool} & - equivalent to \tcode{a_tran.find(ke) != a_tran.end()} & + \effects Equivalent to: \tcode{return a_tran.find(ke) != a_tran.end();} & logarithmic \\ \rowsep \indexordmem{lower_bound}% \tcode{b.lower_bound(k)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. & - returns an iterator pointing to the first element with + \returns An iterator pointing to the first element with key not less than \tcode{k}, or \tcode{b.end()} if such an element is not found. & logarithmic \\ \rowsep @@ -2006,7 +2013,7 @@ \tcode{a_tran.}\br \tcode{lower_bound(kl)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to the first element with + \returns An iterator pointing to the first element with key \tcode{r} such that \tcode{!c(r, kl)}, or \tcode{a_tran.end()} if such an element is not found. & logarithmic \\ \rowsep @@ -2014,7 +2021,7 @@ \indexordmem{upper_bound}% \tcode{b.upper_bound(k)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. & - returns an iterator pointing to the first element with + \returns An iterator pointing to the first element with key greater than \tcode{k}, or \tcode{b.end()} if such an element is not found. & logarithmic \\ \rowsep @@ -2022,7 +2029,7 @@ \tcode{a_tran.}\br \tcode{upper_bound(ku)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to the first element with + \returns An iterator pointing to the first element with key \tcode{r} such that \tcode{c(ku, r)}, or \tcode{a_tran.end()} if such an element is not found. & logarithmic \\ \rowsep @@ -2031,15 +2038,15 @@ \tcode{b.equal_range(k)} & \tcode{pair<\brk{}iterator, iterator>}; \tcode{pair<\brk{}const_iterator, const_iterator>} for constant \tcode{b}. & - equivalent to \tcode{make_pair(b.lower_bound(k), b.upper_bound(k))}. & + \effects Equivalent to: \tcode{return make_pair(b.lower_bound(k), b.upper_bound(k));} & logarithmic \\ \rowsep \tcode{a_tran.}\br \tcode{equal_range(ke)} & \tcode{pair<\brk{}iterator, iterator>}; \tcode{pair<\brk{}const_iterator, const_iterator>} for constant \tcode{a_tran}. & - equivalent to \tcode{make_pair(}\br - \tcode{a_tran.lower_bound(ke), a_tran.upper_bound(ke))}. & + \effects Equivalent to: \tcode{return make_pair(}\br + \tcode{a_tran.lower_bound(ke), a_tran.upper_bound(ke));} & logarithmic \\ \end{libreqtab4b} @@ -2086,7 +2093,7 @@ When an associative container is constructed by passing a comparison object the container shall not store a pointer or reference to the passed object, even if that object is passed by reference. -When an associative container is copied, either through a copy constructor +When an associative container is copied, through either a copy constructor or an assignment operator, the target container shall then use the comparison object from the container being copied, @@ -2291,8 +2298,9 @@ \end{itemize} where \tcode{r1} and \tcode{r2} are keys of elements in \tcode{a_tran}, \item \tcode{n} denotes a value of type \tcode{size_type}, -\item \tcode{z} denotes a value of type \tcode{float}, and -\item \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}. +\item \tcode{z} denotes a value of type \tcode{float}, +\item \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}, and +\item \tcode{hk} and \tcode{hke} denote values of type \tcode{size_t}. \end{itemize} % Local command to index names as members of all unordered containers. @@ -2332,18 +2340,18 @@ \indexunordmem{value_type}% \tcode{X::value_type} (\tcode{unordered_set} and \tcode{unordered_multiset} only) & \tcode{Key} & - \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & + \expects \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \tcode{X::value_type} (\tcode{unordered_map} and \tcode{unordered_multimap} only) & \tcode{pair} & - \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & + \expects \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \indexunordmem{hasher}% \tcode{X::hasher} & \tcode{Hash} -& \tcode{Hash} shall be a unary function object type such that the expression +& \expects \tcode{Hash} is a unary function object type such that the expression \tcode{hf(k)} has type \tcode{size_t}.% & compile time \\ \rowsep @@ -2353,8 +2361,8 @@ & \tcode{Hash::transparent_key_equal} if such a \grammarterm{qualified-id} is valid and denotes a type\iref{temp.deduct}; otherwise, \tcode{Pred}. -& \requires\ \tcode{Pred} is \oldconcept{CopyConstructible}.\br - \tcode{Pred} shall be a binary predicate that takes two arguments +& \expects \tcode{Pred} meets the \oldconcept{CopyConstructible} requirements.\br + \tcode{Pred} is a binary predicate that takes two arguments of type \tcode{Key}. \tcode{Pred} is an equivalence relation.% & compile time \\ \rowsep @@ -2403,7 +2411,7 @@ % \tcode{X(n, hf)}\br \tcode{X a(n, hf);} & \tcode{X} -& \requires\ \tcode{key_equal} is \oldconcept{DefaultConstructible}.\br +& \expects \tcode{key_equal} meets the \oldconcept{DefaultConstructible} requirements.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2412,7 +2420,7 @@ % \tcode{X(n)}\br \tcode{X a(n);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}.\br +& \expects \tcode{hasher} and \tcode{key_equal} meet the \oldconcept{DefaultConstructible} requirements.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2421,7 +2429,7 @@ % \tcode{X()}\br \tcode{X a;} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}.\br +& \expects \tcode{hasher} and \tcode{key_equal} meet the \oldconcept{DefaultConstructible} requirements.\br \effects\ Constructs an empty container with an unspecified number of buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2430,7 +2438,7 @@ % \tcode{X(i, j, n, hf, eq)}\br \tcode{X a(i, j, n, hf, eq);} & \tcode{X} -& \requires\ \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{eq} as the key equality predicate, and inserts elements from \tcode{[i, j)} into it. @@ -2440,7 +2448,7 @@ % \tcode{X(i, j, n, hf)}\br \tcode{X a(i, j, n, hf);} & \tcode{X} -& \requires\ \tcode{key_equal} is \oldconcept{DefaultConstructible}. +& \expects \tcode{key_equal} meets the \oldconcept{DefaultConstructible} requirements. \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{key_equal()} as the key @@ -2451,7 +2459,7 @@ % \tcode{X(i, j, n)}\br \tcode{X a(i, j, n);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}. +& \expects \tcode{hasher} and \tcode{key_equal} meet the \oldconcept{DefaultConstructible} requirements. \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} @@ -2463,7 +2471,7 @@ % \tcode{X(i, j)}\br \tcode{X a(i, j);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}. +& \expects \tcode{hasher} and \tcode{key_equal} meet the \oldconcept{DefaultConstructible} requirements. \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with an unspecified number of buckets, using \tcode{hasher()} as the hash function and @@ -2515,7 +2523,7 @@ % \tcode{a = il} & \tcode{X\&} -& \requires\ \tcode{value_type} is +& \expects \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X} and \oldconcept{CopyAssignable}.\br \effects\ Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All @@ -2526,14 +2534,14 @@ \indexunordmem{hash_function}% \tcode{b.hash_function()} & \tcode{hasher} -& Returns \tcode{b}'s hash function.% +& \returns \tcode{b}'s hash function.% & constant \\ \rowsep % \indexunordmem{key_eq}% \tcode{b.key_eq()} & \tcode{key_equal} -& Returns \tcode{b}'s key equality predicate.% +& \returns \tcode{b}'s key equality predicate.% & constant \\ \rowsep % @@ -2541,7 +2549,7 @@ \indexunordmem{emplace}% \tcode{a_uniq.} \tcode{emplace(args)} & \tcode{pair} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. @@ -2554,7 +2562,7 @@ \tcode{a_eq.}\tcode{emplace(args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. & @@ -2564,7 +2572,7 @@ \indexunordmem{emplace_hint}% \tcode{a.emplace_hint(p, args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Equivalent to \tcode{a.emplace(} \tcode{std::forward<\brk{}Args>(\brk{}args)...)}. Return value is an iterator pointing to the element with the key equivalent to the newly inserted element. The \tcode{const_iterator} \tcode{p} @@ -2576,8 +2584,8 @@ \indexunordmem{insert}% \tcode{a_uniq.insert(t)} & \tcode{pair} -& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be +& \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} @@ -2589,8 +2597,8 @@ % \tcode{a_eq.insert(t)} & \tcode{iterator} -& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be +& \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t}, and returns an iterator pointing to the newly inserted element. @@ -2599,8 +2607,8 @@ % \tcode{a.insert(p, t)} & \tcode{iterator} -& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be - \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be +& \expects If \tcode{t} is a non-const rvalue, \tcode{value_type} is + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}.\br \effects Equivalent to \tcode{a.insert(t)}. Return value is an iterator pointing to the element with the key equivalent to that of \tcode{t}. The @@ -2611,8 +2619,8 @@ % \tcode{a.insert(i, j)} & \tcode{void} -& \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \requires \tcode{i} and \tcode{j} are not iterators in \tcode{a}.\br +& \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}.\br \effects Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% & Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. Worst case \bigoh{N(\tcode{a.size()}\brk{}+\brk{}1)}. @@ -2627,9 +2635,9 @@ \tcode{a_uniq.}\br \tcode{insert(nh)} & \tcode{insert_return_type} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a_uniq.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect. Otherwise, inserts the + \effects If \tcode{nh} is empty, has no effect. Otherwise, inserts the element owned by \tcode{nh} if and only if there is no element in the container with a key equivalent to \tcode{nh.key()}.\br \ensures If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, @@ -2644,9 +2652,9 @@ \tcode{a_eq.}\br \tcode{insert(nh)} & \tcode{iterator} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a_eq.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. + \effects If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. Otherwise, inserts the element owned by \tcode{nh} and returns an iterator pointing to the newly inserted element.\br \ensures \tcode{nh} is empty. & @@ -2654,9 +2662,9 @@ % \tcode{a.insert(q, nh)} & \tcode{iterator} & - \requires \tcode{nh} is empty or + \expects \tcode{nh} is empty or \tcode{a.get_allocator() == nh.get_allocator()}.\br - \effects{} If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. + \effects If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. Otherwise, inserts the element owned by \tcode{nh} if and only if there is no element with key equivalent to \tcode{nh.key()} in containers with unique keys; always inserts the element owned by \tcode{nh} in containers @@ -2670,21 +2678,21 @@ \indexunordmem{extract}% \tcode{a.extract(k)} & \tcode{node_type} & - Removes an element in the container with key equivalent to \tcode{k}. - Returns a \tcode{node_type} owning the element if found, otherwise an empty + \effects Removes an element in the container with key equivalent to \tcode{k}.\br + \returns A \tcode{node_type} owning the element if found, otherwise an empty \tcode{node_type}. & Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \tcode{a.extract(q)} & \tcode{node_type} & - Removes the element pointed to by \tcode{q}. - Returns a \tcode{node_type} owning that element. & + \effects Removes the element pointed to by \tcode{q}.\br + \returns A \tcode{node_type} owning that element. & Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \indexunordmem{merge}% \tcode{a.merge(a2)} & \tcode{void} & - \requires \tcode{a.get_allocator() == a2.get_allocator()}.\br + \expects \tcode{a.get_allocator() == a2.get_allocator()}.\br Attempts to extract each element in \tcode{a2} and insert it into \tcode{a} using the hash function and key equality predicate of \tcode{a}. In containers with unique keys, if there is an element in \tcode{a} with @@ -2701,31 +2709,31 @@ \indexunordmem{erase}% \tcode{a.erase(k)} & \tcode{size_type} -& Erases all elements with key equivalent to \tcode{k}. Returns -the number of elements erased. +& \effects Erases all elements with key equivalent to \tcode{k}.\br + \returns The number of elements erased. & Average case \bigoh{\tcode{a.count(k)}}. Worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \tcode{a.erase(q)} & \tcode{iterator} -& Erases the element pointed to by \tcode{q}. Returns the - iterator immediately following \tcode{q} prior to the erasure. +& \effects Erases the element pointed to by \tcode{q}.\br + \returns The iterator immediately following \tcode{q} prior to the erasure. & Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \tcode{a.erase(r)} & \tcode{iterator} -& Erases the element pointed to by \tcode{r}. Returns the - iterator immediately following \tcode{r} prior to the erasure. +& \effects Erases the element pointed to by \tcode{r}.\br + \returns The iterator immediately following \tcode{r} prior to the erasure. & Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \tcode{a.erase(q1, q2)} & \tcode{iterator} -& Erases all elements in the range \tcode{[q1, q2)}. Returns - the iterator immediately following the erased elements prior to the - erasure.% +& \effects Erases all elements in the range \tcode{[q1, q2)}.\br + \returns The iterator immediately following the erased elements prior to the + erasure. & Average case linear in \tcode{distance(q1, q2)}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep @@ -2733,37 +2741,70 @@ \indexunordmem{clear}% \tcode{a.clear()} & \tcode{void} -& Erases all elements in the container. - \ensures \tcode{a.empty()} returns \tcode{true}% +& \effects Erases all elements in the container. + \ensures \tcode{a.empty()} is \tcode{true}% & Linear in \tcode{a.size()}. \\ \rowsep % \indexunordmem{find}% \tcode{b.find(k)} & \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{b}. -& Returns an iterator pointing to an element with key equivalent to - \tcode{k}, or \tcode{b.end()} if no such element exists.% +& \returns An iterator pointing to an element with key equivalent to + \tcode{k}, or \tcode{b.end()} if no such element exists. +& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. +\\ \rowsep +% +\tcode{b.find(k, hk)} +& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{b}. +& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br + \returns An iterator pointing to an element with key equivalent to + \tcode{k}, or \tcode{b.end()} if no such element exists. & Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. \\ \rowsep % \tcode{a_tran.find(ke)} & \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{a_tran}. -& Returns an iterator pointing to an element with key equivalent to +& \returns An iterator pointing to an element with key equivalent to + \tcode{ke}, or \tcode{a_tran.end()} if no such element exists. +& Average case \bigoh{1}, + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% +\tcode{a_tran.find(ke, hke)} +& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{a_tran}. +& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br + \returns An iterator pointing to an element with key equivalent to \tcode{ke}, or \tcode{a_tran.end()} if no such element exists.% & Average case \bigoh{1}, - worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid wverfull + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull \\ \rowsep % \indexunordmem{count}% \tcode{b.count(k)} & \tcode{size_type} -& Returns the number of elements with key equivalent to \tcode{k}.% +& \returns The number of elements with key equivalent to \tcode{k}.% +& Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. +\\ \rowsep +% +\tcode{b.count(k, hk)} +& \tcode{size_type} +& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br + \returns The number of elements with key equivalent to \tcode{k}.% & Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. \\ \rowsep % \tcode{a_tran.count(ke)} & \tcode{size_type} -& Returns the number of elements with key equivalent to \tcode{ke}.% +& \returns The number of elements with key equivalent to \tcode{ke}.% +& Average case + \bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}, % avoid overfull + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% +\tcode{a_tran.count(ke, hke)} +& \tcode{size_type} +& \expects \tcode{b.hash_function()(ke)} equals \tcode{hke}.\br + \returns The number of elements with key equivalent to \tcode{ke}.% & Average case \bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}, % avoid overfull worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull @@ -2772,13 +2813,28 @@ \indexunordmem{contains}% \tcode{b.contains(k)} & \tcode{bool} -& Equivalent to \tcode{b.find(k) != b.end()}% +& \effects Equivalent to \tcode{b.find(k) != b.end()}% +& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. +\\ \rowsep +% +\tcode{b.contains(k, hk)} +& \tcode{bool} +& \expects \tcode{b.hash_function()(ke)} equals \tcode{hke}.\br + \effects Equivalent to \tcode{b.find(k) != b.end()}% & Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. \\ \rowsep % \tcode{a_tran.contains(ke)} & \tcode{bool} -& Equivalent to \tcode{a_tran.find(ke) != a_tran.end()}% +& \effects Equivalent to \tcode{a_tran.find(ke) != a_tran.end()}% +& Average case \bigoh{1}, + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% +\tcode{a_tran.contains(ke, hke)} +& \tcode{bool} +& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br + \effects Equivalent to \tcode{a_tran.find(ke, hke) != a_tran.end()}% & Average case \bigoh{1}, worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull \\ \rowsep @@ -2787,7 +2843,18 @@ \tcode{b.equal_range(k)} & \tcode{pair}; \br \tcode{pair} for const \tcode{b}. -& Returns a range containing all elements with keys equivalent to +& \returns A range containing all elements with keys equivalent to + \tcode{k}. Returns \tcode{make_pair(b.end(), b.end())} if + no such elements exist.% +& Average case \bigoh{\tcode{b.count(k)}}. Worst case + \bigoh{\tcode{b.size()}}. +\\ \rowsep +% +\tcode{b.equal_range(k, hk)} +& \tcode{pair}; \br + \tcode{pair} for const \tcode{b}. +& \expects \tcode{b.hash_function()(k)} equals \tcode{hk}.\br + \returns A range containing all elements with keys equivalent to \tcode{k}. Returns \tcode{make_pair(b.end(), b.end())} if no such elements exist.% & Average case \bigoh{\tcode{b.count(k)}}. Worst case @@ -2797,7 +2864,19 @@ \tcode{a_tran.equal_range(ke)} & \tcode{pair}; \br \tcode{pair} for const \tcode{a_tran}. -& Returns a range containing all elements with keys equivalent to +& \returns A range containing all elements with keys equivalent to + \tcode{ke}. Returns \tcode{make_pair(a_tran.end(), a_tran.end())} if + no such elements exist.% +& Average case + \bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}. % avoid overfull + Worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% +\tcode{a_tran.equal_range(ke, hke)} +& \tcode{pair}; \br + \tcode{pair} for const \tcode{a_tran}. +& \expects \tcode{a_tran.hash_function()(ke)} equals \tcode{hke}.\br + \returns A range containing all elements with keys equivalent to \tcode{ke}. Returns \tcode{make_pair(a_tran.end(), a_tran.end())} if no such elements exist.% & Average case @@ -2807,14 +2886,14 @@ \indexunordmem{bucket_count}% \tcode{b.bucket_count()} & \tcode{size_type} -& Returns the number of buckets that \tcode{b} contains.% +& \returns The number of buckets that \tcode{b} contains.% & Constant \\ \rowsep % \indexunordmem{max_bucket_count}% \tcode{b.max_bucket_count()} & \tcode{size_type} -& Returns an upper bound on the number of buckets that \tcode{b} might +& \returns An upper bound on the number of buckets that \tcode{b} might ever contain.% & Constant \\ \rowsep @@ -2823,18 +2902,18 @@ \tcode{b.bucket(k)} & \tcode{size_type} & - \requires \tcode{b.bucket_count() > 0}.\br - Returns the index of the bucket in which elements with keys equivalent + \expects \tcode{b.bucket_count() > 0}.\br + \returns The index of the bucket in which elements with keys equivalent to \tcode{k} would be found, if any such element existed. - \ensures the return value shall be in the range \tcode{[0, b.bucket_count())}.% + \ensures The return value shall be in the range \tcode{[0, b.bucket_count())}.% & Constant \\ \rowsep % \indexunordmem{bucket_size}% \tcode{b.bucket_size(n)} & \tcode{size_type} -& \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - Returns the number of elements in the $\tcode{n}^\text{th}$ bucket.% +& \expects \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. + \returns The number of elements in the $\tcode{n}^\text{th}$ bucket.% & \bigoh{\tcode{b.bucket_}\-\tcode{size(n)}} \\ \rowsep % @@ -2842,8 +2921,8 @@ \tcode{b.begin(n)} & \tcode{local_iterator}; \br \tcode{const_local_iterator} for const \tcode{b}. -& \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - \tcode{b.begin(n)} returns an iterator referring to the +& \expects \tcode{n} is in the range \tcode{[0, b.bucket_count())}.\br + \returns An iterator referring to the first element in the bucket. If the bucket is empty, then \tcode{b.begin(n) == b.end(n)}.% & Constant @@ -2853,8 +2932,8 @@ \tcode{b.end(n)} & \tcode{local_iterator}; \br \tcode{const_local_iterator} for const \tcode{b}. -& \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - \tcode{b.end(n)} returns an iterator which is the past-the-end +& \expects \tcode{n} is in the range \tcode{[0, b.bucket_count())}.\br + \returns An iterator which is the past-the-end value for the bucket.% & Constant \\ \rowsep @@ -2862,8 +2941,8 @@ \indexunordmem{cbegin}% \tcode{b.cbegin(n)} & \tcode{const_local_iterator} -& \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - \tcode{b.cbegin(n)} returns an iterator referring to the +& \expects \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}.\br + \returns An iterator referring to the first element in the bucket. If the bucket is empty, then \tcode{b.cbegin(n) == b.cend(n)}.% & Constant @@ -2872,8 +2951,8 @@ \indexunordmem{cend}% \tcode{b.cend(n)} & \tcode{const_local_iterator} -& \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}.% - \tcode{b.cend(n)} returns an iterator which is the past-the-end +& \expects \tcode{n} is in the range \tcode{[0, b.bucket_count())}.% + \returns An iterator which is the past-the-end value for the bucket.% & Constant \\ \rowsep @@ -2881,14 +2960,14 @@ \indexunordmem{load_factor}% \tcode{b.load_factor()} & \tcode{float} -& Returns the average number of elements per bucket.% +& \returns The average number of elements per bucket.% & Constant \\ \rowsep % \indexunordmem{max_load_factor}% \tcode{b.max_load_factor()} & \tcode{float} -& Returns a positive number that the container attempts to keep the load factor +& \returns A positive number that the container attempts to keep the load factor less than or equal to. The container automatically increases the number of buckets as necessary to keep the load factor below this number.% @@ -2897,7 +2976,7 @@ % \tcode{a.max_load_factor(z)} & \tcode{void} -& \requires \tcode{z} shall be positive. +& \expects \tcode{z} is positive. May change the container's maximum load factor, using \tcode{z} as a hint.% & Constant \\ \rowsep @@ -3087,8 +3166,9 @@ template constexpr void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); - template class tuple_size; - template class tuple_element; + // \ref{array.tuple}, tuple interface to class template \tcode{array} + template struct tuple_size; + template struct tuple_element; template struct tuple_size>; template @@ -3132,9 +3212,9 @@ void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); - template + template void erase(deque& c, const U& value); - template + template void erase_if(deque& c, Predicate pred); namespace pmr { @@ -3144,7 +3224,7 @@ } \end{codeblock} -\rSec2[forward_list.syn]{Header \tcode{} synopsis} +\rSec2[forward.list.syn]{Header \tcode{} synopsis} \indexhdr{forward_list}% @@ -3172,9 +3252,9 @@ void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); - template + template void erase(forward_list& c, const U& value); - template + template void erase_if(forward_list& c, Predicate pred); namespace pmr { @@ -3212,9 +3292,9 @@ void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); - template + template void erase(list& c, const U& value); - template + template void erase_if(list& c, Predicate pred); namespace pmr { @@ -3252,9 +3332,9 @@ void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); - template + template void erase(vector& c, const U& value); - template + template void erase_if(vector& c, Predicate pred); // \ref{vector.bool}, class \tcode{vector} @@ -3394,7 +3474,7 @@ \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{(is_same_v \&\& ...)} is \tcode{true}. Otherwise the program is ill-formed. +\mandates \tcode{(is_same_v \&\& ...)} is \tcode{true}. \end{itemdescr} \rSec3[array.members]{Member functions} @@ -3456,9 +3536,8 @@ \end{itemdecl} \begin{itemdescr} -\pnum\remarks -This function shall not participate in overload resolution -unless \tcode{N == 0} or \tcode{is_swappable_v} is \tcode{true}. +\pnum +\constraints \tcode{N == 0} or \tcode{is_swappable_v} is \tcode{true}. \pnum\effects As if by \tcode{x.swap(y)}. @@ -3500,10 +3579,11 @@ \begin{itemdescr} \pnum -\requires \tcode{I < N}. The program is ill-formed if \tcode{I} is out of bounds. +\mandates +\tcode{I < N} is \tcode{true}. \pnum -\cvalue The type T. +\cvalue The type \tcode{T}. \end{itemdescr} \indexlibrarymember{array}{get}% @@ -3520,7 +3600,8 @@ \begin{itemdescr} \pnum -\requires \tcode{I < N}. The program is ill-formed if \tcode{I} is out of bounds. +\mandates +\tcode{I < N} is \tcode{true}. \pnum \returns A reference to the $\tcode{I}^\text{th}$ element of \tcode{a}, @@ -3696,7 +3777,8 @@ \tcode{n} default-inserted elements using the specified allocator. \pnum -\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -3716,7 +3798,8 @@ using the specified allocator. \pnum -\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. \pnum \complexity @@ -3750,13 +3833,14 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. + \pnum \effects If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements from the sequence. Otherwise, appends \tcode{sz - size()} default-inserted elements to the sequence. - -\pnum -\requires \tcode{T} shall be \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrary{\idxcode{resize}!\idxcode{deque}}% @@ -3765,14 +3849,14 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. + \pnum \effects If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements from the sequence. Otherwise, appends \tcode{sz - size()} copies of \tcode{c} to the sequence. - -\pnum -\requires \tcode{T} shall be -\oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrarymember{shrink_to_fit}{deque}% @@ -3782,22 +3866,31 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects \tcode{shrink_to_fit} is a non-binding request to reduce memory use but does not change the size of the sequence. \begin{note} The request is non-binding to allow latitude for implementation-specific optimizations. \end{note} -If an exception is thrown other than by the move constructor -of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. +If the size is equal to the old capacity, or +if an exception is thrown other than by the move constructor +of a non-\oldconcept{CopyInsertable} \tcode{T}, +then there are no effects. \pnum -\complexity Linear in the size of the sequence. +\complexity +If the size is not equal to the old capacity, +linear in the size of the sequence; +otherwise constant. \pnum -\remarks \tcode{shrink_to_fit} invalidates all the references, pointers, and iterators -referring to the elements in the sequence as well as the past-the-end iterator. +\remarks +If the size is not equal to the old capacity, +then invalidates all the references, pointers, and iterators +referring to the elements in the sequence, +as well as the past-the-end iterator. \end{itemdescr} \rSec3[deque.modifiers]{Modifiers} @@ -3850,7 +3943,7 @@ \complexity The complexity is linear in the number of elements inserted plus the lesser of the distances to the beginning and end of the deque. -Inserting a single element either at the beginning or end of a deque always takes constant time +Inserting a single element at either the beginning or end of a deque always takes constant time and causes a single call to a constructor of \tcode{T}. \end{itemdescr} @@ -3890,7 +3983,7 @@ \indexlibrary{\idxcode{erase}!\idxcode{deque}}% \begin{itemdecl} -template +template void erase(deque& c, const U& value); \end{itemdecl} @@ -3902,7 +3995,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{deque}}% \begin{itemdecl} -template +template void erase_if(deque& c, Predicate pred); \end{itemdecl} @@ -4094,11 +4187,11 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{forward_list} object with \tcode{n} -default-inserted elements using the specified allocator. +\expects \tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum -\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. +\effects Constructs a \tcode{forward_list} object with \tcode{n} +default-inserted elements using the specified allocator. \pnum \complexity Linear in \tcode{n}. @@ -4111,10 +4204,10 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{forward_list} object with \tcode{n} copies of \tcode{value} using the specified allocator. +\expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. \pnum -\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. +\effects Constructs a \tcode{forward_list} object with \tcode{n} copies of \tcode{value} using the specified allocator. \pnum \complexity Linear in \tcode{n}. @@ -4223,7 +4316,7 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. \pnum @@ -4240,7 +4333,7 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. \pnum @@ -4259,9 +4352,9 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. -\tcode{first} and \tcode{last} are not iterators in \tcode{*this}. +Neither \tcode{first} nor \tcode{last} are iterators in \tcode{*this}. \pnum \effects Inserts copies of elements in \range{first}{last} after \tcode{position}. @@ -4294,7 +4387,7 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. \pnum @@ -4312,7 +4405,7 @@ \begin{itemdescr} \pnum -\requires The iterator following \tcode{position} is dereferenceable. +\expects The iterator following \tcode{position} is dereferenceable. \pnum \effects Erases the element pointed to by the iterator following \tcode{position}. @@ -4331,7 +4424,7 @@ \begin{itemdescr} \pnum -\requires All iterators in the range \orange{position}{last} are dereferenceable. +\expects All iterators in the range \orange{position}{last} are dereferenceable. \pnum \effects Erases the elements in the range \orange{position}{last}. @@ -4349,13 +4442,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. + \pnum \effects If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} default-inserted elements at the end of the list. - -\pnum -\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \begin{itemdecl} @@ -4363,13 +4456,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. + \pnum \effects If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} copies of \tcode{c} at the end of the list. - -\pnum -\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} @@ -4404,10 +4497,10 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. -\tcode{get_allocator() == x.get_allocator()}. -\tcode{addressof(x) != this}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. +\tcode{addressof(x) != this} is \tcode{true}. \pnum \effects Inserts the contents of \tcode{x} after @@ -4431,10 +4524,10 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. The iterator following \tcode{i} is a dereferenceable iterator in \tcode{x}. -\tcode{get_allocator() == x.get_allocator()}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. \pnum \effects Inserts the element following \tcode{i} into \tcode{*this}, following @@ -4461,11 +4554,11 @@ \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a +\expects \tcode{position} is \tcode{before_begin()} or is a dereferenceable iterator in the range \range{begin()}{end()}. \orange{first}{last} is a valid range in \tcode{x}, and all iterators in the range \orange{first}{last} are dereferenceable. \tcode{position} is not an iterator in the range \orange{first}{last}. -\tcode{get_allocator() == x.get_allocator()}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. \pnum \effects Inserts elements in the range \orange{first}{last} after \tcode{position} and @@ -4541,7 +4634,7 @@ \begin{itemdescr} \pnum -\requires \tcode{*this} and \tcode{x} are both sorted with respect to +\expects \tcode{*this} and \tcode{x} are both sorted with respect to the comparator \tcode{operator<} (for the first two overloads) or \tcode{comp} (for the last two overloads), and \tcode{get_allocator() == x.get_allocator()} is \tcode{true}. @@ -4556,8 +4649,7 @@ \tcode{x}. \pnum -\remarks Stable\iref{algorithm.stable}. The behavior is undefined if -\tcode{get_allocator() != x.get_allocator()}. +\remarks Stable\iref{algorithm.stable}. \pnum \complexity At most \tcode{distance(begin(), @@ -4597,11 +4689,11 @@ \complexity Linear time. \end{itemdescr} -\rSec3[forward_list.erasure]{Erasure} +\rSec3[forward.list.erasure]{Erasure} \indexlibrary{\idxcode{erase}!\idxcode{forward_list}}% \begin{itemdecl} -template +template void erase(forward_list& c, const U& value); \end{itemdecl} @@ -4613,7 +4705,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{forward_list}}% \begin{itemdecl} -template +template void erase_if(forward_list& c, Predicate pred); \end{itemdecl} @@ -4819,11 +4911,11 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{list} with -\tcode{n} default-inserted elements using the specified allocator. +\expects \tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum -\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. +\effects Constructs a \tcode{list} with +\tcode{n} default-inserted elements using the specified allocator. \pnum \complexity @@ -4837,6 +4929,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. + \pnum \effects Constructs a @@ -4847,9 +4942,6 @@ \tcode{value}, using the specified allocator. -\pnum -\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. - \pnum \complexity Linear in @@ -4884,6 +4976,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. + \pnum \effects If \tcode{size() < sz}, @@ -4896,11 +4991,6 @@ advance(it, sz); erase(it, end()); \end{codeblock} - - -\pnum -\requires \tcode{T} shall be -\oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrary{\idxcode{resize}!\idxcode{list}}% @@ -4909,6 +4999,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. + \pnum \effects As if by: @@ -4923,9 +5016,6 @@ else ; // do nothing \end{codeblock} - -\pnum -\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} \rSec3[list.modifiers]{Modifiers} @@ -5020,8 +5110,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{addressof(x) != this}. +\expects +\tcode{addressof(x) != this} is \tcode{true}. \pnum \effects @@ -5058,10 +5148,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{i} -is a valid dereferenceable iterator of -\tcode{x}. +\expects +\tcode{i} is a valid dereferenceable iterator of \tcode{x}. \pnum \effects @@ -5107,14 +5195,9 @@ \begin{itemdescr} \pnum -\requires -\tcode{[first, last)} -is a valid range in -\tcode{x}. -The program has undefined behavior if -\tcode{position} -is an iterator in the range -\range{first}{last}. +\expects +\tcode{[first, last)} is a valid range in \tcode{x}. +\tcode{position} is not an iterator in the range \range{first}{last}. \pnum \effects @@ -5140,7 +5223,7 @@ \pnum \complexity Constant time if -\tcode{\&x == this}; +\tcode{addressof(x) == this}; otherwise, linear time. \end{itemdescr} @@ -5223,11 +5306,12 @@ \begin{itemdescr} \pnum -\requires +\expects Both the list and the argument list shall be sorted with respect to the comparator \tcode{operator<} (for the first two overloads) or \tcode{comp} (for the last two overloads). +\tcode{get_allocator() != x.get_allocator()} is \tcode{true}. \pnum \effects @@ -5244,8 +5328,7 @@ \pnum \remarks Stable\iref{algorithm.stable}. If \tcode{addressof(x) != this}, the range \tcode{[x.begin(), x.end())} is empty after the merge. -No elements are copied by this operation. The behavior is undefined if -\tcode{get_allocator() != x.get_allocator()}. +No elements are copied by this operation. \pnum \complexity @@ -5302,7 +5385,7 @@ \indexlibrary{\idxcode{erase}!\idxcode{list}}% \begin{itemdecl} -template +template void erase(list& c, const U& value); \end{itemdecl} @@ -5314,7 +5397,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{list}}% \begin{itemdecl} -template +template void erase_if(list& c, Predicate pred); \end{itemdecl} @@ -5498,11 +5581,11 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{vector} with \tcode{n} -default-inserted elements using the specified allocator. +\expects \tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum -\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. +\effects Constructs a \tcode{vector} with \tcode{n} +default-inserted elements using the specified allocator. \pnum \complexity Linear in \tcode{n}. @@ -5516,12 +5599,12 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{vector} with \tcode{n} -copies of \tcode{value}, using the specified allocator. +\expects \tcode{T} is +\oldconcept{CopyInsertable} into \tcode{*this}. \pnum -\requires \tcode{T} shall be -\oldconcept{CopyInsertable} into \tcode{*this}. +\effects Constructs a \tcode{vector} with \tcode{n} +copies of \tcode{value}, using the specified allocator. \pnum \complexity Linear in \tcode{n}. @@ -5584,7 +5667,7 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. +\expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects @@ -5619,13 +5702,14 @@ \pnum \remarks Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence. +referring to the elements in the sequence, as well as the past-the-end iterator. +\begin{note} +If no reallocation happens, they remain valid. +\end{note} No reallocation shall take place during insertions that happen -after a call to -\tcode{reserve()} -until the time when an insertion would make the size of the vector -greater than the value of -\tcode{capacity()}. +after a call to \tcode{reserve()} +until an insertion would make the size of the vector +greater than the value of \tcode{capacity()}. \end{itemdescr} \indexlibrary{\idxcode{shrink_to_fit}!\idxcode{vector}}% @@ -5635,7 +5719,7 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. +\expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects \tcode{shrink_to_fit} is a non-binding request to reduce @@ -5648,12 +5732,16 @@ of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. \pnum -\complexity Linear in the size of the sequence. +\complexity +If reallocation happens, +linear in the size of the sequence. \pnum \remarks Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator. +\begin{note} If no reallocation happens, they remain valid. +\end{note} \end{itemdescr} \indexlibrary{\idxcode{swap}!\idxcode{vector}}% @@ -5683,15 +5771,15 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{T} is +\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. + \pnum \effects If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements from the sequence. Otherwise, appends \tcode{sz - size()} default-inserted elements to the sequence. -\pnum -\requires \tcode{T} shall be -\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. - \pnum \remarks If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. @@ -5704,14 +5792,14 @@ \begin{itemdescr} \pnum +\pnum +\expects \tcode{T} is +\oldconcept{CopyInsertable} into \tcode{*this}. + \effects If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements from the sequence. Otherwise, appends \tcode{sz - size()} copies of \tcode{c} to the sequence. -\pnum -\requires \tcode{T} shall be -\oldconcept{CopyInsertable} into \tcode{*this}. - \pnum \remarks If an exception is thrown there are no effects. \end{itemdescr} @@ -5757,8 +5845,13 @@ \remarks Causes reallocation if the new size is greater than the old capacity. Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence. -If no reallocation happens, all the iterators and references before the insertion point remain valid. +referring to the elements in the sequence, as well as the past-the-end iterator. +If no reallocation happens, then +references, pointers, and iterators +before the insertion point remain valid +but those at or after the insertion point, +including the past-the-end iterator, +are invalidated. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of @@ -5772,7 +5865,10 @@ \pnum \complexity -The complexity is linear in the number of elements inserted plus the distance +If reallocation happens, +linear in the number of elements of the resulting vector; +otherwise, +linear in the number of elements inserted plus the distance to the end of the vector. \end{itemdescr} @@ -5806,7 +5902,7 @@ \indexlibrary{\idxcode{erase}!\idxcode{vector}}% \begin{itemdecl} -template +template void erase(vector& c, const U& value); \end{itemdecl} @@ -5818,7 +5914,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{vector}}% \begin{itemdecl} -template +template void erase_if(vector& c, Predicate pred); \end{itemdecl} @@ -6064,7 +6160,7 @@ map& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(map& c, Predicate pred); // \ref{multimap}, class template \tcode{multimap} @@ -6096,7 +6192,7 @@ multimap& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(multimap& c, Predicate pred); namespace pmr { @@ -6147,7 +6243,7 @@ set& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(set& c, Predicate pred); // \ref{multiset}, class template \tcode{multiset} @@ -6178,7 +6274,7 @@ multiset& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(multiset& c, Predicate pred); namespace pmr { @@ -6540,17 +6636,15 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + \pnum \effects The first form is equivalent to \tcode{return emplace(std::forward

(x))}. The second form is equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. - -\pnum -\remarks -These signatures shall not participate in overload resolution -unless \tcode{is_constructible_v} is -\tcode{true}. \end{itemdescr} \indexlibrarymember{try_emplace}{map}% @@ -6563,8 +6657,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{map} +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(k)}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -6601,8 +6695,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{map} +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(std::move(k))}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -6639,9 +6733,12 @@ \begin{itemdescr} \pnum -\requires -\tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{map} +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{k}, \tcode{forward(obj)}. \pnum @@ -6676,9 +6773,12 @@ \begin{itemdescr} \pnum -\requires -\tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{map} +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{move(k)}, \tcode{forward(obj)}. \pnum @@ -6707,7 +6807,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{map}}% \begin{itemdecl} -template +template void erase_if(map& c, Predicate pred); \end{itemdecl} @@ -7015,24 +7115,22 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{is_constructible_v} is \tcode{true}. + \pnum \effects The first form is equivalent to \tcode{return emplace(std::forward

(x))}. The second form is equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. - -\pnum -\remarks -These signatures shall not participate in overload resolution -unless \tcode{is_constructible_v} is -\tcode{true}. \end{itemdescr} \rSec3[multimap.erasure]{Erasure} \indexlibrary{\idxcode{erase_if}!\idxcode{multimap}}% \begin{itemdecl} -template +template void erase_if(multimap& c, Predicate pred); \end{itemdecl} @@ -7311,7 +7409,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{set}}% \begin{itemdecl} -template +template void erase_if(set& c, Predicate pred); \end{itemdecl} @@ -7588,7 +7686,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{multiset}}% \begin{itemdecl} -template +template void erase_if(multiset& c, Predicate pred); \end{itemdecl} @@ -7670,10 +7768,10 @@ unordered_multimap& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(unordered_map& c, Predicate pred); - template + template void erase_if(unordered_multimap& c, Predicate pred); namespace pmr { @@ -7742,10 +7840,10 @@ unordered_multiset& y) noexcept(noexcept(x.swap(y))); - template + template void erase_if(unordered_set& c, Predicate pred); - template + template void erase_if(unordered_multiset& c, Predicate pred); namespace pmr { @@ -7938,22 +8036,40 @@ // map operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; - template + iterator find(const key_type& k, size_t hash); + const_iterator find(const key_type& k, size_t hash) const; + template iterator find(const K& k); - template + template const_iterator find(const K& k) const; + template + iterator find(const K& k, size_t hash); + template + const_iterator find(const K& k, size_t hash) const; size_type count(const key_type& k) const; - template + size_type count(const key_type& k, size_t hash) const; + template size_type count(const K& k) const; + template + size_type count(const K& k, size_t hash) const; bool contains(const key_type& k) const; - template + bool contains(const key_type& k, size_t hash) const; + template bool contains(const K& k) const; + template + bool contains(const K& k, size_t hash) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - template + pair equal_range(const key_type& k, size_t hash); + pair equal_range(const key_type& k, size_t hash) const; + template pair equal_range(const K& k); - template + template pair equal_range(const K& k) const; + template + pair equal_range(const K& k, size_t hash); + template + pair equal_range(const K& k, size_t hash) const; // \ref{unord.map.elem}, element access mapped_type& operator[](const key_type& k); @@ -8143,12 +8259,13 @@ \end{itemdecl} \begin{itemdescr} + \pnum -\effects Equivalent to: \tcode{return emplace(std::forward

(obj));} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{is_constructible_v} is \tcode{true}. +\effects Equivalent to: \tcode{return emplace(std::forward

(obj));} \end{itemdescr} \indexlibrarymember{unordered_map}{insert}% @@ -8159,12 +8276,12 @@ \begin{itemdescr} \pnum -\effects Equivalent to: -\tcode{return emplace_hint(hint, std::forward

(obj));} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{is_constructible_v} is \tcode{true}. +\effects Equivalent to: +\tcode{return emplace_hint(hint, std::forward

(obj));} \end{itemdescr} \indexlibrarymember{try_emplace}{unordered_map}% @@ -8177,8 +8294,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(k)}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -8215,8 +8332,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(std::move(k))}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -8253,10 +8370,13 @@ \begin{itemdescr} \pnum -\requires -\tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} -from \tcode{k}, \tcode{std::forward(obj)}. +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +from \tcode{k}, \tcode{std::forward\brk{}(obj)}. \pnum \effects @@ -8290,10 +8410,12 @@ \begin{itemdescr} \pnum -\requires -\tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} -from \tcode{std::move(k)}, \tcode{std::forward(obj)}. +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\expects +\tcode{value_type} is \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} +from \tcode{std::move(k)}, \tcode{std::\brk{}forward(obj)}. \pnum \effects @@ -8321,7 +8443,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{unordered_map}}% \begin{itemdecl} -template +template void erase_if(unordered_map& c, Predicate pred); \end{itemdecl} @@ -8502,22 +8624,40 @@ // map operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; - template + iterator find(const key_type& k, size_t hash); + const_iterator find(const key_type& k, size_t hash) const; + template iterator find(const K& k); - template + template const_iterator find(const K& k) const; + template + iterator find(const K& k, size_t hash); + template + const_iterator find(const K& k, size_t hash) const; size_type count(const key_type& k) const; - template + size_type count(const key_type& k, size_t hash) const; + template size_type count(const K& k) const; + template + size_type count(const K& k, size_t hash) const; bool contains(const key_type& k) const; - template + bool contains(const key_type& k, size_t hash) const; + template bool contains(const K& k) const; + template + bool contains(const K& k, size_t hash) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - template + pair equal_range(const key_type& k, size_t hash); + pair equal_range(const key_type& k, size_t hash) const; + template pair equal_range(const K& k); - template + template pair equal_range(const K& k) const; + template + pair equal_range(const K& k, size_t hash); + template + pair equal_range(const K& k, size_t hash) const; // bucket interface size_type bucket_count() const noexcept; @@ -8665,11 +8805,11 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{return emplace(std::forward

(obj));} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{is_constructible_v} is \tcode{true}. +\effects Equivalent to: \tcode{return emplace(std::forward

(obj));} \end{itemdescr} \indexlibrarymember{unordered_multimap}{insert}% @@ -8680,19 +8820,19 @@ \begin{itemdescr} \pnum -\effects Equivalent to: -\tcode{return emplace_hint(hint, std::forward

(obj));} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{is_constructible_v} is \tcode{true}. +\effects Equivalent to: +\tcode{return emplace_hint(hint, std::forward

(obj));} \end{itemdescr} \rSec3[unord.multimap.erasure]{Erasure} \indexlibrary{\idxcode{erase_if}!\idxcode{unordered_multimap}}% \begin{itemdecl} -template +template void erase_if(unordered_multimap& c, Predicate pred); \end{itemdecl} @@ -8864,22 +9004,40 @@ // set operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; - template + iterator find(const key_type& k, size_t hash); + const_iterator find(const key_type& k, size_t hash) const; + template iterator find(const K& k); - template + template const_iterator find(const K& k) const; + template + iterator find(const K& k, size_t hash); + template + const_iterator find(const K& k, size_t hash) const; size_type count(const key_type& k) const; - template + size_type count(const key_type& k, size_t hash) const; + template size_type count(const K& k) const; + template + size_type count(const K& k, size_t hash) const; bool contains(const key_type& k) const; - template + bool contains(const key_type& k, size_t hash) const; + template bool contains(const K& k) const; + template + bool contains(const K& k, size_t hash) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - template + pair equal_range(const key_type& k, size_t hash); + pair equal_range(const key_type& k, size_t hash) const; + template pair equal_range(const K& k); - template + template pair equal_range(const K& k) const; + template + pair equal_range(const K& k, size_t hash); + template + pair equal_range(const K& k, size_t hash) const; // bucket interface size_type bucket_count() const noexcept; @@ -9010,7 +9168,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{unordered_set}}% \begin{itemdecl} -template +template void erase_if(unordered_set& c, Predicate pred); \end{itemdecl} @@ -9188,22 +9346,40 @@ // set operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; - template + iterator find(const key_type& k, size_t hash); + const_iterator find(const key_type& k, size_t hash) const; + template iterator find(const K& k); - template + template const_iterator find(const K& k) const; + template + iterator find(const K& k, size_t hash); + template + const_iterator find(const K& k, size_t hash) const; size_type count(const key_type& k) const; - template + size_type count(const key_type& k, size_t hash) const; + template size_type count(const K& k) const; + template + size_type count(const K& k, size_t hash) const; bool contains(const key_type& k) const; - template + bool contains(const key_type& k, size_t hash) const; + template bool contains(const K& k) const; + template + bool contains(const K& k, size_t hash) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - template + pair equal_range(const key_type& k, size_t hash); + pair equal_range(const key_type& k, size_t hash) const; + template pair equal_range(const K& k); - template + template pair equal_range(const K& k) const; + template + pair equal_range(const K& k, size_t hash); + template + pair equal_range(const K& k, size_t hash) const; // bucket interface size_type bucket_count() const noexcept; @@ -9333,7 +9509,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{unordered_multiset}}% \begin{itemdecl} -template +template void erase_if(unordered_multiset& c, Predicate pred); \end{itemdecl} @@ -9392,9 +9568,6 @@ namespace std { template> class queue; - template, - class Compare = less> - class priority_queue; template bool operator==(const queue& x, const queue& y); @@ -9411,9 +9584,18 @@ template void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; + + template, + class Compare = less> + class priority_queue; + template void swap(priority_queue& x, priority_queue& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; } \end{codeblock} @@ -9441,6 +9623,8 @@ template void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; } \end{codeblock} @@ -9679,9 +9863,8 @@ \begin{itemdescr} \pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_swappable_v} is \tcode{true}. +\constraints +\tcode{is_swappable_v} is \tcode{true}. \pnum \effects As if by \tcode{x.swap(y)}. @@ -9794,8 +9977,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{x} shall define a strict weak ordering\iref{alg.sorting}. +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. \pnum \effects @@ -9819,8 +10002,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{x} shall define a strict weak ordering\iref{alg.sorting}. +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. \pnum \effects @@ -9983,9 +10166,8 @@ \begin{itemdescr} \pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_swappable_v} is \tcode{true} and +\constraints +\tcode{is_swappable_v} is \tcode{true} and \tcode{is_swappable_v} is \tcode{true}. \pnum @@ -10228,9 +10410,8 @@ \begin{itemdescr} \pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_swappable_v} is \tcode{true}. +\constraints +\tcode{is_swappable_v} is \tcode{true}. \pnum \effects As if by \tcode{x.swap(y)}. @@ -10249,24 +10430,32 @@ \begin{codeblock} namespace std { // constants - inline constexpr ptrdiff_t dynamic_extent = -1; + inline constexpr size_t dynamic_extent = numeric_limits::max(); // \ref{views.span}, class template span - template + template class span; // \ref{span.objectrep}, views of object representation - template - span(sizeof(ElementType)) * Extent> + template + span as_bytes(span s) noexcept; - template - span(sizeof(ElementType)) * Extent> + template + span as_writable_bytes(span s) noexcept; + + // \ref{span.tuple}, tuple interface + template class tuple_size; + template class tuple_element; + template + struct tuple_size>; + template + struct tuple_size>; // not defined + template + struct tuple_element>; + template + constexpr ElementType& get(span) noexcept; } \end{codeblock} @@ -10296,16 +10485,18 @@ \indexlibrary{\idxcode{span}}% \begin{codeblock} namespace std { - template + template class span { public: // constants and types using element_type = ElementType; using value_type = remove_cv_t; - using index_type = ptrdiff_t; + using index_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; + using const_pointer = const element_type*; using reference = element_type&; + using const_reference = const element_type&; using iterator = @\impdefx{type of \tcode{span::iterator}}@; using const_iterator = @\impdefx{type of \tcode{span::const_iterator}}@; using reverse_iterator = std::reverse_iterator; @@ -10327,7 +10518,7 @@ template constexpr span(const Container& cont); constexpr span(const span& other) noexcept = default; - template + template constexpr span(const span& s) noexcept; ~span() noexcept = default; @@ -10335,11 +10526,11 @@ constexpr span& operator=(const span& other) noexcept = default; // \ref{span.sub}, subviews - template + template constexpr span first() const; - template + template constexpr span last() const; - template + template constexpr span subspan() const; constexpr span first(index_type count) const; @@ -10350,11 +10541,12 @@ // \ref{span.obs}, observers constexpr index_type size() const noexcept; constexpr index_type size_bytes() const noexcept; - constexpr bool empty() const noexcept; + [[nodiscard]] constexpr bool empty() const noexcept; // \ref{span.elem}, element access constexpr reference operator[](index_type idx) const; - constexpr reference operator()(index_type idx) const; + constexpr reference front() const; + constexpr reference back() const; constexpr pointer data() const noexcept; // \ref{span.iterators}, iterator support @@ -10392,36 +10584,33 @@ \tcode{ElementType} is required to be a complete object type that is not an abstract class type. -\pnum -If \tcode{Extent} is negative and not equal to \tcode{dynamic_extent}, -the program is ill-formed. - \rSec3[span.cons]{Constructors, copy, and assignment} \indexlibrary{\idxcode{span}!constructor}% \begin{itemdecl} constexpr span() noexcept; \end{itemdecl} + \begin{itemdescr} \pnum -\ensures -\tcode{size() == 0 \&\& data() == nullptr}. +\constraints +\tcode{Extent <= 0} is \tcode{true}. \pnum -\remarks -This constructor shall not participate in overload resolution -unless \tcode{Extent <= 0} is \tcode{true}. +\ensures +\tcode{size() == 0 \&\& data() == nullptr}. \end{itemdescr} \indexlibrary{\idxcode{span}!constructor}% \begin{itemdecl} constexpr span(pointer ptr, index_type count); \end{itemdecl} + \begin{itemdescr} \pnum -\requires \range{ptr}{ptr + count} shall be a valid range. +\expects \range{ptr}{ptr + count} is a valid range. If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{count} shall be equal to \tcode{extent}. +then \tcode{count} is equal to \tcode{extent}. \pnum \effects @@ -10440,12 +10629,13 @@ \begin{itemdecl} constexpr span(pointer first, pointer last); \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\range{first}{last} shall be a valid range. +\expects +\range{first}{last} is a valid range. If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{last - first} shall be equal to \tcode{extent}. +then \tcode{last - first} is equal to \tcode{extent}. \pnum \effects @@ -10466,7 +10656,15 @@ template constexpr span(array& arr) noexcept; template constexpr span(const array& arr) noexcept; \end{itemdecl} + \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{extent == dynamic_extent || N == extent} is \tcode{true}, and +\item \tcode{remove_pointer_t(*)[]} is convertible to \tcode{ElementType(*)[]}. +\end{itemize} + \pnum \effects Constructs a \tcode{span} that is a view over the supplied array. @@ -10474,14 +10672,6 @@ \pnum \ensures \tcode{size() == N \&\& data() == data(arr)}. - -\pnum -\remarks -These constructors shall not participate in overload resolution unless: -\begin{itemize} -\item \tcode{extent == dynamic_extent || N == extent} is \tcode{true}, and -\item \tcode{remove_pointer_t(*)[]} is convertible to \tcode{ElementType(*)[]}. -\end{itemize} \end{itemdescr} \indexlibrary{\idxcode{span}!constructor}% @@ -10489,12 +10679,22 @@ template constexpr span(Container& cont); template constexpr span(const Container& cont); \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\range{data(cont)}{data(cont) + size(cont)} shall be a valid range. -If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{size(cont)} shall be equal to \tcode{extent}. +\constraints +\begin{itemize} +\item \tcode{extent == dynamic_extent} is \tcode{true}, +\item \tcode{Container} is not a specialization of \tcode{span}, +\item \tcode{Container} is not a specialization of \tcode{array}, +\item \tcode{is_array_v} is \tcode{false}, +\item \tcode{data(cont)} and \tcode{size(cont)} are both well-formed, and +\item \tcode{remove_pointer_t(*)[]} is convertible to \tcode{ElementType(*)[]}. +\end{itemize} + +\pnum +\expects +\range{data(cont)}{data(cont) + size(cont)} is a valid range. \pnum \effects @@ -10507,23 +10707,13 @@ \pnum \throws What and when \tcode{data(cont)} and \tcode{size(cont)} throw. - -\pnum -\remarks -These constructors shall not participate in overload resolution unless: -\begin{itemize} -\item \tcode{Container} is not a specialization of \tcode{span}, -\item \tcode{Container} is not a specialization of \tcode{array}, -\item \tcode{is_array_v} is \tcode{false}, -\item \tcode{data(cont)} and \tcode{size(cont)} are both well-formed, and -\item \tcode{remove_pointer_t(*)[]} is convertible to \tcode{ElementType(*)[]}. -\end{itemize} \end{itemdescr} \indexlibrary{\idxcode{span}!constructor}% \begin{itemdecl} constexpr span(const span& other) noexcept = default; \end{itemdecl} + \begin{itemdescr} \pnum \ensures @@ -10532,10 +10722,18 @@ \indexlibrary{\idxcode{span}!constructor}% \begin{itemdecl} -template +template constexpr span(const span& s) noexcept; \end{itemdecl} + \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{Extent == dynamic_extent || Extent == OtherExtent} is \tcode{true}, and +\item \tcode{OtherElementType(*)[]} is convertible to \tcode{ElementType(*)[]}. +\end{itemize} + \pnum \effects Constructs a \tcode{span} that is a view over the range @@ -10544,20 +10742,13 @@ \pnum \ensures \tcode{size() == s.size() \&\& data() == s.data()}. - -\pnum -\remarks -This constructor shall not participate in overload resolution unless: -\begin{itemize} -\item \tcode{Extent == dynamic_extent || Extent == OtherExtent} is \tcode{true}, and -\item \tcode{OtherElementType(*)[]} is convertible to \tcode{ElementType(*)[]}. -\end{itemize} \end{itemdescr} \indexlibrary{\idxcode{operator=}!\idxcode{span}}% \begin{itemdecl} constexpr span& operator=(const span& other) noexcept = default; \end{itemdecl} + \begin{itemdescr} \pnum \ensures @@ -10568,12 +10759,13 @@ \indexlibrarymember{span}{first}% \begin{itemdecl} -template constexpr span first() const; +template constexpr span first() const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\tcode{0 <= Count \&\& Count <= size()}. +\expects +\tcode{Count <= size()} is \tcode{true}. \pnum \effects @@ -10582,12 +10774,13 @@ \indexlibrarymember{span}{last}% \begin{itemdecl} -template constexpr span last() const; +template constexpr span last() const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\tcode{0 <= Count \&\& Count <= size()}. +\expects +\tcode{Count <= size()} is \tcode{true}. \pnum \effects @@ -10596,16 +10789,17 @@ \indexlibrarymember{span}{subspan}% \begin{itemdecl} -template +template constexpr span subspan() const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires +\expects \begin{codeblock} -(0 <= Offset && Offset <= size()) -&& (Count == dynamic_extent || Count >= 0 && Offset + Count <= size()) +Offset <= size() && (Count == dynamic_extent || Offset + Count <= size()) \end{codeblock} +is \tcode{true}. \pnum \effects @@ -10629,10 +10823,11 @@ \begin{itemdecl} constexpr span first(index_type count) const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\tcode{0 <= count \&\& count <= size()}. +\expects +\tcode{count <= size()} is \tcode{true}. \pnum \effects @@ -10643,10 +10838,11 @@ \begin{itemdecl} constexpr span last(index_type count) const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\tcode{0 <= count 0 \&\& count <= size()}. +\expects +\tcode{count <= size()} is \tcode{true}. \pnum \effects @@ -10658,13 +10854,14 @@ constexpr span subspan( index_type offset, index_type count = dynamic_extent) const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires +\expects \begin{codeblock} -(0 <= offset && offset <= size()) -&& (count == dynamic_extent || count >= 0 && offset + count <= size()) +offset <= size() && (count == dynamic_extent || offset + count <= size()) \end{codeblock} +is \tcode{true}. \pnum \effects @@ -10680,6 +10877,7 @@ \begin{itemdecl} constexpr index_type size() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10690,6 +10888,7 @@ \begin{itemdecl} constexpr index_type size_bytes() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10698,8 +10897,9 @@ \indexlibrarymember{span}{empty}% \begin{itemdecl} -constexpr bool empty() const noexcept; +[[nodiscard]] constexpr bool empty() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10709,25 +10909,55 @@ \rSec3[span.elem]{Element access} \indexlibrary{\idxcode{operator[]}!\idxcode{span}}% -\indexlibrary{\idxcode{operator()}!\idxcode{span}}% \begin{itemdecl} constexpr reference operator[](index_type idx) const; -constexpr reference operator()(index_type idx) const; \end{itemdecl} + \begin{itemdescr} \pnum -\requires -\tcode{0 <= idx \&\& idx < size()}. +\expects +\tcode{idx < size()} is \tcode{true}. \pnum \effects Equivalent to: \tcode{return *(data() + idx);} \end{itemdescr} +\indexlibrarymember{span}{front}% +\begin{itemdecl} +constexpr reference front() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty()} is \tcode{false}. + +\pnum +\effects +Equivalent to: \tcode{return *data();} +\end{itemdescr} + +\indexlibrarymember{span}{back}% +\begin{itemdecl} +constexpr reference back() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty()} is \tcode{false}. + +\pnum +\effects +Equivalent to: \tcode{return *(data() + (size() - 1));} +\end{itemdescr} + \indexlibrarymember{span}{data}% \begin{itemdecl} constexpr pointer data() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10740,6 +10970,7 @@ \begin{itemdecl} constexpr iterator begin() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \returns @@ -10752,6 +10983,7 @@ \begin{itemdecl} constexpr iterator end() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \returns @@ -10762,6 +10994,7 @@ \begin{itemdecl} constexpr reverse_iterator rbegin() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10772,6 +11005,7 @@ \begin{itemdecl} constexpr reverse_iterator rend() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \returns @@ -10782,6 +11016,7 @@ \begin{itemdecl} constexpr const_iterator cbegin() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \returns @@ -10794,6 +11029,7 @@ \begin{itemdecl} constexpr const_iterator cend() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \returns @@ -10804,6 +11040,7 @@ \begin{itemdecl} constexpr const_reverse_iterator crbegin() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10814,6 +11051,7 @@ \begin{itemdecl} constexpr const_reverse_iterator crend() const noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10825,12 +11063,11 @@ \indexlibrary{\idxcode{as_bytes}}% \begin{itemdecl} -template - span(sizeof(ElementType)) * Extent> +template + span as_bytes(span s) noexcept; \end{itemdecl} + \begin{itemdescr} \pnum \effects @@ -10839,19 +11076,58 @@ \indexlibrary{\idxcode{as_writable_bytes}}% \begin{itemdecl} -template - span(sizeof(ElementType)) * Extent> +template + span as_writable_bytes(span s) noexcept; \end{itemdecl} + \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return \{reinterpret_cast(s.data()), s.size_bytes()\};} +\end{itemdescr} + +\rSec3[span.tuple]{Tuple interface} +\indexlibrary{\idxcode{tuple_size}}% +\begin{itemdecl} +template + struct tuple_size> + : integral_constant { }; +\end{itemdecl} + +\indexlibrary{\idxcode{tuple_element}}% +\begin{itemdecl} +tuple_element>::type +\end{itemdecl} + +\begin{itemdescr} \pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_const_v} is \tcode{false}. +\mandates +\tcode{Extent != dynamic_extent \&\& I < Extent} is \tcode{true}. + +\pnum +\cvalue +The type \tcode{ElementType}. +\end{itemdescr} + +\indexlibrary{\idxcode{get}}% +\begin{itemdecl} +template + constexpr ElementType& get(span s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{Extent != dynamic_extent \&\& I < Extent} is \tcode{true}. + +\pnum +\returns +A reference to the $\tcode{I}^\text{th}$ element of \tcode{s}, +where indexing is zero-based. \end{itemdescr} diff --git a/source/declarations.tex b/source/declarations.tex index 591d7c5c4d..dc6707cef2 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -25,6 +25,7 @@ deduction-guide\br explicit-instantiation\br explicit-specialization\br + export-declaration\br linkage-specification\br namespace-definition\br empty-declaration\br @@ -50,7 +51,7 @@ \begin{bnf} \nontermdef{alias-declaration}\br - \terminal{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;} + \keyword{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;} \end{bnf} \begin{bnf} @@ -62,8 +63,8 @@ \begin{bnf} \nontermdef{static_assert-declaration}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{,} string-literal \terminal{)} \terminal{;} + \keyword{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br + \keyword{static_assert} \terminal{(} constant-expression \terminal{,} string-literal \terminal{)} \terminal{;} \end{bnf} \begin{bnf} @@ -183,9 +184,11 @@ \pnum A \grammarterm{simple-declaration} with an \grammarterm{identifier-list} is called a \defn{structured binding declaration}\iref{dcl.struct.bind}. -The \grammarterm{decl-specifier-seq} shall -contain only the \grammarterm{type-specifier} \tcode{auto}\iref{dcl.spec.auto} -and \grammarterm{cv-qualifier}{s}. +If the \grammarterm{decl-specifier-seq} contains +any \grammarterm{decl-specifier} other than +\tcode{static}, \tcode{thread_local}, \tcode{auto}\iref{dcl.spec.auto}, or +\grammarterm{cv-qualifier}{s}, +the program is ill-formed. The \grammarterm{initializer} shall be of the form ``\tcode{=} \grammarterm{assignment-expression}'', of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'', @@ -250,11 +253,11 @@ storage-class-specifier\br defining-type-specifier\br function-specifier\br - \terminal{friend}\br - \terminal{typedef}\br - \terminal{constexpr}\br - \terminal{consteval}\br - \terminal{inline} + \keyword{friend}\br + \keyword{typedef}\br + \keyword{constexpr}\br + \keyword{consteval}\br + \keyword{inline} \end{bnf} \begin{bnf} @@ -332,10 +335,10 @@ \begin{bnf} \nontermdef{storage-class-specifier}\br - \terminal{static}\br - \terminal{thread_local}\br - \terminal{extern}\br - \terminal{mutable} + \keyword{static}\br + \keyword{thread_local}\br + \keyword{extern}\br + \keyword{mutable} \end{bnf} At most one \grammarterm{storage-class-specifier} shall appear in a given @@ -370,8 +373,9 @@ The \tcode{thread_local} specifier indicates that the named entity has thread storage duration\iref{basic.stc.thread}. It shall be applied only -to the declaration of a variable of namespace -or block scope or to the declaration of a static data member. +to the declaration of a variable of namespace or block scope, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of a static data member. When \tcode{thread_local} is applied to a variable of block scope the \grammarterm{storage-class-specifier} \tcode{static} is implied if no other \grammarterm{storage-class-specifier} appears in the @@ -379,8 +383,11 @@ \pnum \indextext{restriction!\idxcode{static}}% -The \tcode{static} specifier shall be applied only to the declaration of a variable or -function or to the declaration of an anonymous union\iref{class.union.anon}. There can be no +The \tcode{static} specifier shall be applied only +to the declaration of a variable or function, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of an anonymous union\iref{class.union.anon}. +There can be no \tcode{static} function declarations within a block, nor any \tcode{static} function parameters. A \tcode{static} specifier used in the declaration of a variable declares the variable to have static storage @@ -500,14 +507,14 @@ \begin{bnf} \nontermdef{function-specifier}\br - \terminal{virtual}\br + \keyword{virtual}\br explicit-specifier \end{bnf} \begin{bnf} \nontermdef{explicit-specifier}\br - \terminal{explicit} \terminal{(} constant-expression \terminal{)}\br - \terminal{explicit} + \keyword{explicit} \terminal{(} constant-expression \terminal{)}\br + \keyword{explicit} \end{bnf} \pnum @@ -810,7 +817,10 @@ each of its parameter types shall be a literal type; \item -its \grammarterm{function-body} shall not contain +it shall not be a coroutine\iref{dcl.fct.def.coroutine}; + +\item +its \grammarterm{function-body} shall not enclose\iref{stmt.stmt} \begin{itemize} \item an \grammarterm{asm-definition}, \item a \tcode{goto} statement, @@ -822,7 +832,7 @@ \end{itemize} \begin{note} A \grammarterm{function-body} that is \tcode{= delete} or \tcode{= default} -contains none of the above. +encloses none of the above. \end{note} \end{itemize} @@ -955,7 +965,7 @@ a call to a constexpr function can appear in a constant expression\iref{expr.const} and \item -copy elision is mandatory in a constant expression\iref{class.copy.elision}. +copy elision is not performed in a constant expression\iref{class.copy.elision}. \end{itemize} \pnum @@ -1025,27 +1035,46 @@ been declared inline. \pnum -An inline function or variable shall be defined in every translation unit in which -it is odr-used and shall have exactly the same definition in every -case\iref{basic.def.odr}. +If an inline function or variable +is odr-used in a translation unit, +a definition of it shall be reachable from the end of that translation unit, +and it shall have exactly the same definition +in every such translation unit\iref{basic.def.odr}. \begin{note} A call to the inline function or a use of the inline variable may be encountered before its definition appears in the translation unit. \end{note} -If the definition of a function or variable appears in a translation unit before its +If a definition of a function or variable is reachable +at the point of its first declaration as inline, the program is ill-formed. If a function or variable -with external linkage is declared inline in one translation unit, it -shall be declared inline in all translation units in which it appears; -no diagnostic is required. An inline function or variable with external -linkage shall have the same address in all translation units. +with external or module linkage +is declared inline in one translation unit, +there shall be a reachable inline declaration +in all translation units in which it is declared; +no diagnostic is required. +An inline function or variable +with external or module linkage +shall have the same address in all translation units. \begin{note} A \tcode{static} local variable in an inline -function with external linkage always refers to the same object. +function with external or module linkage +always refers to the same object. A type defined within the body of an inline -function with external linkage is the +function with external or module linkage is the same type in every translation unit. \end{note} +\pnum +An exported inline function or variable +shall be defined in the translation unit +containing its exported declaration, +outside the \grammarterm{private-module-fragment} (if any). +\begin{note} +There is no restriction on the linkage (or absence thereof) +of entities that the function body of an exported inline function +can reference. A constexpr function\iref{dcl.constexpr} is implicitly inline. +\end{note} + \rSec2[dcl.type]{Type specifiers}% \indextext{specifier!type|see{type specifier}} @@ -1258,24 +1287,24 @@ \begin{bnf} \nontermdef{simple-type-specifier}\br \opt{nested-name-specifier} type-name\br - nested-name-specifier \terminal{template} simple-template-id\br + nested-name-specifier \keyword{template} simple-template-id\br decltype-specifier\br placeholder-type-specifier\br \opt{nested-name-specifier} template-name\br - \terminal{char}\br - \terminal{char8_t}\br - \terminal{char16_t}\br - \terminal{char32_t}\br - \terminal{wchar_t}\br - \terminal{bool}\br - \terminal{short}\br - \terminal{int}\br - \terminal{long}\br - \terminal{signed}\br - \terminal{unsigned}\br - \terminal{float}\br - \terminal{double}\br - \terminal{void} + \keyword{char}\br + \keyword{char8_t}\br + \keyword{char16_t}\br + \keyword{char32_t}\br + \keyword{wchar_t}\br + \keyword{bool}\br + \keyword{short}\br + \keyword{int}\br + \keyword{long}\br + \keyword{signed}\br + \keyword{unsigned}\br + \keyword{float}\br + \keyword{double}\br + \keyword{void} \end{bnf} \begin{bnf} @@ -1310,8 +1339,11 @@ \opt{\tcode{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} is a placeholder for a deduced class type\iref{dcl.type.class.deduct}. -The \grammarterm{template-name} shall name a class template -that is not an injected-class-name. +The \grammarterm{template-name} shall name a class template. +\begin{note} +An injected-class-name is never interpreted as a \grammarterm{template-name} +in contexts where class template argument deduction would be performed\iref{temp.local}. +\end{note} The other \grammarterm{simple-type-specifier}{s} specify either a previously-declared type, a type determined from an @@ -1389,8 +1421,8 @@ \nontermdef{elaborated-type-specifier}\br class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br class-key simple-template-id\br - class-key nested-name-specifier \opt{\terminal{template}} simple-template-id\br - \terminal{enum} \opt{nested-name-specifier} identifier + class-key nested-name-specifier \opt{\keyword{template}} simple-template-id\br + \keyword{enum} \opt{nested-name-specifier} identifier \end{bnf} \pnum @@ -1406,10 +1438,10 @@ \begin{ncsimplebnf} class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br -\terminal{friend} class-key \terminal{\opt{::}} identifier \terminal{;}\br -\terminal{friend} class-key \terminal{\opt{::}} simple-template-id \terminal{;}\br -\terminal{friend} class-key nested-name-specifier identifier \terminal{;}\br -\terminal{friend} class-key nested-name-specifier \terminal{\opt{template}} simple-template-id \terminal{;} +\keyword{friend} class-key \terminal{\opt{::}} identifier \terminal{;}\br +\keyword{friend} class-key \terminal{\opt{::}} simple-template-id \terminal{;}\br +\keyword{friend} class-key nested-name-specifier identifier \terminal{;}\br +\keyword{friend} class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{;} \end{ncsimplebnf} In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains @@ -1471,7 +1503,7 @@ \begin{bnf} \nontermdef{decltype-specifier}\br - \terminal{decltype} \terminal{(} expression \terminal{)} + \keyword{decltype} \terminal{(} expression \terminal{)} \end{bnf} \pnum @@ -1584,8 +1616,8 @@ \begin{bnf} \nontermdef{placeholder-type-specifier}\br - \opt{type-constraint} \terminal{auto}\br - \opt{type-constraint} \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)} + \opt{type-constraint} \keyword{auto}\br + \opt{type-constraint} \keyword{decltype} \terminal{(} \keyword{auto} \terminal{)} \end{bnf} \pnum @@ -1700,6 +1732,17 @@ \end{codeblock} \end{example} +\pnum +An exported function +with a declared return type that uses a placeholder type +shall be defined in the translation unit +containing its exported declaration, +outside the \grammarterm{private-module-fragment} (if any). +\begin{note} +There is no restriction on the linkage of +the deduced return type. +\end{note} + \pnum If the name of an entity with an undeduced placeholder type appears in an expression, the program is ill-formed. Once a @@ -1777,6 +1820,10 @@ A function declared with a return type that uses a placeholder type shall not be \tcode{virtual}\iref{class.virtual}. +\pnum +A function declared with a return type that uses a placeholder type shall not +be a coroutine\iref{dcl.fct.def.coroutine}. + \pnum An explicit instantiation declaration\iref{temp.explicit} does not cause the instantiation of an entity declared using a placeholder type, but it also does @@ -1850,7 +1897,7 @@ is determined using the rules for template argument deduction. Obtain \tcode{P} from \tcode{T} by replacing the occurrences of -\opt{\grammarterm{type-constraint}} \tcode{auto} with either +\opt{\grammarterm{type-constraint}} \tcode{auto} either with a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with \tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules @@ -2134,8 +2181,8 @@ \begin{bnf} \nontermdef{cv-qualifier}\br - \terminal{const}\br - \terminal{volatile} + \keyword{const}\br + \keyword{volatile} \end{bnf} \begin{bnf} @@ -4246,10 +4293,9 @@ of reference type is ill-formed. \pnum -\begin{note} Every -object of static storage duration is -zero-initialized at program startup before any other initialization -takes place. +\begin{note} For every object of static storage duration, +static initialization\iref{basic.start.static} is performed +at program startup before any other initialization takes place. In some cases, additional initialization is done later. \end{note} @@ -4361,9 +4407,25 @@ and the initializer is a string literal, see~\ref{dcl.init.string}. \item If the initializer is \tcode{()}, the object is value-initialized. \item -Otherwise, if the destination type is an array, the program is ill-formed. +Otherwise, if the destination type is an array, +the object is initialized as follows. +Let $x_1$, $\dotsc$, $x_k$ be +the elements of the \grammarterm{expression-list}. +If the destination type is an array of unknown bound, +it is defined as having $k$ elements. +Let $n$ denote the array size after this potential adjustment. +If $k$ is greater than $n$, +the program is ill-formed. +Otherwise, the $i^\text{th}$ array element is copy-initialized with +$x_i$ for each $1 \leq i \leq k$, and +value-initialized for each $k < i \leq n$. +For each $1 \leq i < j \leq n$, +every value computation and side effect associated with +the initialization of the $i^\text{th}$ element of the array +is sequenced before those associated with +the initialization of the $j^\text{th}$ element. \item -If the destination type is a (possibly cv-qualified) class type: +Otherwise, if the destination type is a (possibly cv-qualified) class type: \begin{itemize} \item @@ -4381,12 +4443,60 @@ constructors are considered. The applicable constructors are enumerated\iref{over.match.ctor}, and the best one is chosen -through overload resolution\iref{over.match}. -The constructor so selected +through overload resolution\iref{over.match}. Then: +\begin{itemize} +\item +If overload resolution is successful, +the selected constructor is called to initialize the object, with the initializer expression or \grammarterm{expression-list} as its argument(s). -If no constructor applies, or the overload resolution is -ambiguous, the initialization is ill-formed. +\item +Otherwise, if no constructor is viable, +the destination type is +a (possibly cv-qualified) aggregate class \tcode{A}, and +the initializer is a parenthesized \grammarterm{expression-list}, +the object is initialized as follows. +Let $e_1$, $\dotsc$, $e_n$ be the elements of the aggregate\iref{dcl.init.aggr}. +Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}. +If $k$ is greater than $n$, the program is ill-formed. +The element $e_i$ is copy-initialized with +$x_i$ for $1 \leq i \leq k$. +The remaining elements are initialized with +their default member initializers, if any, and +otherwise are value-initialized. +For each $1 \leq i < j \leq n$, +every value computation and side effect +associated with the initialization of $e_i$ +is sequenced before those associated with the initialization of $e_j$. +\begin{note} +By contrast with direct-list-initialization, +narrowing conversions\iref{dcl.init.list} are permitted, +designators are not permitted, +a temporary object bound to a reference +does not have its lifetime extended\iref{class.temporary}, and +there is no brace elision. +\begin{example} +\begin{codeblock} +struct A { + int a; + int&& r; +}; + +int f(); +int n = 10; + +A a1{1, f()}; // OK, lifetime is extended +A a2(1, f()); // well-formed, but dangling reference +A a3{1.0, 1}; // error: narrowing conversion +A a4(1.0, 1); // well-formed, but dangling reference +A a5(1.0, std::move(n)); // OK +\end{codeblock} +\end{example} +\end{note} +\item +Otherwise, the initialization is ill-formed. +\end{itemize} + \item Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversions that can convert from the @@ -4469,13 +4579,18 @@ \pnum An object whose initialization has completed is deemed to be constructed, -even if no constructor of the object's class +even if the object is of non-class type or +no constructor of the object's class is invoked for the initialization. \begin{note} Such an object might have been value-initialized or initialized by aggregate initialization\iref{dcl.init.aggr} or by an inherited constructor\iref{class.inhctor.init}. \end{note} +Destroying an object of class type invokes the destructor of the class. +Destroying a scalar type has no effect other than +ending the lifetime of the object\iref{basic.life}. +Destroying an array destroys each element in reverse subscript order. \pnum A declaration that specifies the initialization of a variable, @@ -4804,7 +4919,7 @@ \end{example} \pnum -If a reference member is initialized from its default member initializer +If a member has a default member initializer and a potentially-evaluated subexpression thereof is an aggregate initialization that would use that default member initializer, the program is ill-formed. @@ -4817,6 +4932,10 @@ const A& a2 { A{} }; // error }; A a{a,a}; // OK + + struct B { + int n = B{}.n; // error + }; \end{codeblock} \end{example} @@ -5063,9 +5182,9 @@ or \tcode{wchar_t} array can be initialized by an ordinary string literal, -\tcode{char8_t} string literal, -\tcode{char16_t} string literal, -\tcode{char32_t} string literal, or +UTF-8 string literal, +UTF-16 string literal, +UTF-32 string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces\iref{lex.string}. @@ -5166,29 +5285,17 @@ Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'', ``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to ``\cvqual{cv2} \tcode{T2}'' if -\tcode{T1} is the same type as \tcode{T2}, or +\tcode{T1} is similar\iref{conv.qual} to \tcode{T2}, or \tcode{T1} is a base class of \tcode{T2}. ``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible} with ``\cvqual{cv2} \tcode{T2}'' if -\begin{itemize} -\item \tcode{T1} is reference-related to \tcode{T2}, or -\item \tcode{T2} is ``\tcode{noexcept} function'' and \tcode{T1} is ``function'', -where the function types are otherwise the same, -\end{itemize} -and -\cvqual{cv1} -is the same cv-qualification as, or greater cv-qualification than, -\cvqual{cv2}. -In all cases where the reference-related or reference-compatible relationship -of two types is used to establish the validity of a reference binding, and -\tcode{T1} -is a base class of -\tcode{T2}, -a program that necessitates such a binding is ill-formed if -\tcode{T1} -is an inaccessible\iref{class.access} or ambiguous\iref{class.member.lookup} -base class of -\tcode{T2}. +a prvalue of type ``pointer to \cvqual{cv2} \tcode{T2}'' can be converted to +the type ``pointer to \cvqual{cv1} \tcode{T1}'' +via a standard conversion sequence\iref{conv}. +In all cases where the reference-compatible relationship +of two types is used to establish the validity of a reference binding and +the standard conversion sequence would be ill-formed, +a program that necessitates such a binding is ill-formed. \pnum A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by @@ -5586,9 +5693,7 @@ \item Otherwise, if \tcode{T} is a reference type, a prvalue of the type referenced by \tcode{T} is generated. -The prvalue initializes its result object by -copy-list-initialization or direct-list-initialization, -depending on the kind of initialization for the reference. +The prvalue initializes its result object by copy-list-initialization. The prvalue is then used to direct-initialize the reference. \begin{note} As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. \end{note} @@ -5606,6 +5711,10 @@ const int& i1 = { 1 }; // OK const int& i2 = { 1.1 }; // error: narrowing const int (&iar)[2] = { 1, 2 }; // OK: \tcode{iar} is bound to temporary array + +struct A { } a; +struct B { explicit B(const A&); }; +const B &b2{a}; // error: cannot copy-list-initialize \tcode{B} temporary from \tcode{A} \end{codeblock} \end{example} @@ -5794,8 +5903,8 @@ \nontermdef{function-body}\br \opt{ctor-initializer} compound-statement\br function-try-block\br - \terminal{= default ;}\br - \terminal{= delete ;} + \terminal{=} \keyword{default} \terminal{;}\br + \terminal{=} \keyword{delete} \terminal{;} \end{bnf} Any informal reference to the body of a function should be interpreted as a reference to @@ -5924,7 +6033,9 @@ if it were implicitly declared, as follows: \begin{itemize} \item - \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; and + \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; +\item + \tcode{T}$_1$ and \tcode{T}$_2$ may have differing exception specifications; and \item if \tcode{T}$_2$ has a parameter of type \tcode{const C\&}, the corresponding parameter of \tcode{T}$_1$ may be of type \tcode{C\&}. @@ -5959,12 +6070,24 @@ constexpr S() = default; // ill-formed: implicit \tcode{S()} is not \tcode{constexpr} S(int a = 0) = default; // ill-formed: default argument void operator=(const S&) = default; // ill-formed: non-matching return type - ~S() noexcept(false) = default; // deleted: exception specification does not match + ~S() noexcept(false) = default; // OK, despite mismatched exception specification private: int i; S(S&); // OK: private copy constructor }; S::S(S&) = default; // OK: defines copy constructor + +struct T { + T(); + T(T &&) noexcept(false); +}; +struct U { + T t; + U(); + U(U &&) noexcept = default; +}; +U u1; +U u2 = static_cast(u1); // OK, calls \tcode{std::terminate} if \tcode{T::T(T\&\&)} throws \end{codeblock} \end{example} @@ -6091,6 +6214,266 @@ \end{example}% \indextext{definition!function|)} +\rSec2[dcl.fct.def.coroutine]{Coroutine definitions}% +\indextext{definition!coroutine}% + +\pnum +A function is a \defn{coroutine} if it contains a +\grammarterm{coroutine-return-statement}\iref{stmt.return.coroutine}, +an \grammarterm{await-expression}\iref{expr.await}, +or a \grammarterm{yield-expression}\iref{expr.yield}. +The \grammarterm{parameter-declaration-clause} of the coroutine shall not +terminate with an ellipsis that is not part of +a \grammarterm{parameter-declaration}. + +\pnum +\begin{example} +\begin{codeblock} +task f(); + +task g1() { + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} + +template +task g2(Args&&...) { // OK, ellipsis is a pack expansion + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} + +task g3(int a, ...) { // error: variable parameter list not allowed + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} +\end{codeblock} +\end{example} + +\pnum +\indextext{promise type|see{coroutine!promise type}}% +The \defnx{promise type}{coroutine!promise type} of a coroutine is +\tcode{std::coroutine_traits::promise_type}, +where +\tcode{R} is the return type of the function, and +$\tcode{P}_1 \dotsc \tcode{P}_n$ are the sequence of types of the function parameters, +preceded by the type of the implicit object parameter\iref{over.match.funcs} +if the coroutine is a non-static member function. +The promise type shall be a class type. + +\pnum +In the following, $\tcode{p}_i$ is an lvalue of type $\tcode{P}_i$, +where +$\tcode{p}_1$ denotes \tcode{*this} and +$\tcode{p}_{i+1}$ denotes the $i^\textrm{th}$ function parameter +for a non-static member function, and +$\tcode{p}_i$ denotes +the $i^\textrm{th}$ function parameter otherwise. + +\pnum +A coroutine behaves as if its \grammarterm{function-body} were replaced by: +\begin{ncsimplebnf} +\terminal{\{}\br +\bnfindent promise-type \exposid{promise} promise-constructor-arguments \terminal{;}\br +% FIXME: \bnfindent \exposid{promise}\terminal{.get_return_object()} \terminal{;} +% ... except that it's not a discarded-value expression +\bnfindent \terminal{co_await} \terminal{\exposid{promise}.initial_suspend()} \terminal{;}\br +\bnfindent \terminal{try \{}\br +\bnfindent\bnfindent function-body\br +\bnfindent \terminal{\} catch ( ... ) \{}\br +\bnfindent\bnfindent \terminal{\exposid{promise}.unhandled_exception()} \terminal{;}\br +\bnfindent \terminal{\}}\br +\exposid{final-suspend} \terminal{:}\br +\bnfindent \terminal{co_await} \terminal{\exposid{promise}.final_suspend()} \terminal{;}\br +\terminal{\}} +\end{ncsimplebnf} +where +\begin{itemize} +\item +the \grammarterm{await-expression} containing +the call to \tcode{initial_suspend} +is the \defn{initial suspend point}, and +\item +the \grammarterm{await-expression} containing +the call to \tcode{final_suspend} +is the \defn{final suspend point}, and +\item +\placeholder{promise-type} denotes the promise type, and +\item +the object denoted by the exposition-only name \exposid{promise} +is the \defn{promise object} of the coroutine, and +\item +the label denoted by the name \exposid{final-suspend} +is defined for exposition only\iref{stmt.return.coroutine}, and +\item +\placeholder{promise-constructor-arguments} is determined as follows: +overload resolution is performed on a promise constructor call created by +assembling an argument list with lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$. If a viable +constructor is found\iref{over.match.viable}, then +\placeholder{promise-constructor-arguments} is +\tcode{(p$_1$, $\dotsc$, p$_n$)}, otherwise +\placeholder{promise-constructor-arguments} is empty. +\end{itemize} + +\pnum +The \grammarterm{unqualified-id}{s} \tcode{return_void} +and \tcode{return_value} are looked up in the scope of the promise type. +If both are found, the program is ill-formed. +\begin{note} +If the \grammarterm{unqualified-id} \tcode{return_void} is found, flowing off +the end of a coroutine is equivalent to a \tcode{co_return} with no operand. +Otherwise, flowing off the end of a coroutine +results in undefined behavior\iref{stmt.return.coroutine}. +\end{note} + +\pnum +The expression \tcode{\exposid{promise}.get_return_object()} is used +to initialize +the glvalue result or prvalue result object of a call to a coroutine. +The call to \tcode{get_return_object} +is sequenced before +the call to \tcode{initial_suspend} +and is invoked at most once. + +\pnum +A suspended coroutine can be resumed to continue execution by invoking +a resumption member function\iref{coroutine.handle.resumption} +of a coroutine handle\iref{coroutine.handle} +that refers to the coroutine. +The function that invoked a resumption member function is +called the \defnx{resumer}{coroutine!resumer}. +Invoking a resumption member function for a coroutine +that is not suspended results in undefined behavior. + +\pnum +An implementation may need to allocate additional storage for a coroutine. +This storage is known as the \defn{coroutine state} and is obtained by calling +a non-array allocation function\iref{basic.stc.dynamic.allocation}. +The allocation function's name is looked up in the scope of the promise type. +If this lookup fails, the allocation function's name is looked up in the +global scope. +If the lookup finds an allocation function in the scope of the promise type, +overload resolution is performed on a function call created by assembling an +argument list. The first argument is the amount of space requested, and has +type \tcode{std::size_t}. +The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ are the succeeding arguments. +If no viable function is found\iref{over.match.viable}, +overload resolution is performed again +on a function call created by passing just +the amount of space required as an argument of type \tcode{std::size_t}. + +\pnum +The \grammarterm{unqualified-id} \tcode{get_return_object_on_allocation_failure} +is looked up in the scope of the promise type by class member access +lookup\iref{basic.lookup.classref}. +If any declarations are found, then the result +of a call to an allocation function used to obtain storage for the coroutine +state is assumed to return \tcode{nullptr} if it fails to obtain storage, +and if a global allocation function is selected, +the \tcode{::operator new(size_t, nothrow_t)} form is used. +The allocation function used in this case shall have a non-throwing +\grammarterm{noexcept-specification}. +If the allocation function returns \tcode{nullptr}, the coroutine returns +control to the caller of the coroutine and the return value is obtained by a +call to \tcode{T::get_return_object_on_allocation_failure()}, where \tcode{T} +is the promise type. + +\begin{example} +\begin{codeblock} +#include +#include + +// \tcode{::operator new(size_t, nothrow_t)} will be used if allocation is needed +struct generator { + struct promise_type; + using handle = std::coroutine_handle; + struct promise_type { + int current_value; + static auto get_return_object_on_allocation_failure() { return generator{nullptr}; } + auto get_return_object() { return generator{handle::from_promise(*this)}; } + auto initial_suspend() { return std::suspend_always{}; } + auto final_suspend() { return std::suspend_always{}; } + void unhandled_exception() { std::terminate(); } + void return_void() {} + auto yield_value(int value) { + current_value = value; + return std::suspend_always{}; + } + }; + bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; } + int current_value() { return coro.promise().current_value; } + generator(generator const&) = delete; + generator(generator && rhs) : coro(rhs.coro) { rhs.coro = nullptr; } + ~generator() { if (coro) coro.destroy(); } +private: + generator(handle h) : coro(h) {} + handle coro; +}; +generator f() { co_yield 1; co_yield 2; } +int main() { + auto g = f(); + while (g.move_next()) std::cout << g.current_value() << std::endl; +} +\end{codeblock} +\end{example} + +\pnum +The coroutine state is destroyed when control flows off the end of the +coroutine or the \tcode{destroy} member +function\iref{coroutine.handle.resumption} +of a coroutine handle\iref{coroutine.handle} +that refers to the coroutine +is invoked. +In the latter case objects with automatic storage duration that +are in scope at the suspend point are destroyed in the reverse order of the +construction. The storage for the coroutine state is released by calling a +non-array deallocation function\iref{basic.stc.dynamic.deallocation}. +If \tcode{destroy} is called for a coroutine that is not suspended, the +program has undefined behavior. + +\pnum +The deallocation function's name is looked up in the scope of the promise type. +If this lookup fails, the deallocation function's name is looked up in the +global scope. If deallocation function lookup finds both a usual deallocation +function with only a pointer parameter and a usual deallocation function with +both a pointer parameter and a size parameter, then the selected deallocation +function shall be the one with two parameters. Otherwise, the selected +deallocation function shall be the function with one parameter. If no usual +deallocation function is found, the program is ill-formed. +The selected deallocation function shall be called with the address of the +block of storage to be reclaimed as its first argument. If a deallocation +function with a parameter of type \tcode{std::size_t} is used, the size of +the block is passed as the corresponding argument. + +\pnum +When a coroutine is invoked, a copy is created for each coroutine parameter. +Each such copy is an object with automatic storage duration that is +direct-initialized from an lvalue referring to the corresponding parameter if +the parameter is an lvalue reference, and from an xvalue referring to it +otherwise. A reference to a parameter in the function-body of the coroutine +and in the call to the coroutine promise constructor is replaced by a +reference to its copy. +The initialization and destruction of each parameter copy occurs in the +context of the called coroutine. +Initializations of parameter copies are sequenced before the call to the +coroutine promise constructor and indeterminately sequenced with respect to +each other. +The lifetime of parameter copies ends immediately after the lifetime of the +coroutine promise object ends. +\begin{note} +If a coroutine has a parameter passed by reference, resuming the coroutine +after the lifetime of the entity referred to by that parameter has ended is +likely to result in undefined behavior. +\end{note} + +\pnum +If the evaluation of the expression +\tcode{\exposid{promise}.unhandled_exception()} exits via an exception, +the coroutine is considered suspended at the final suspend point. + +\pnum +The expression \tcode{co_await} \tcode{\exposid{promise}.final_suspend()} +shall not be potentially-throwing\iref{except.spec}. + \rSec1[dcl.struct.bind]{Structured binding declarations}% \indextext{structured binding declaration}% \indextext{declaration!structured binding|see{structured binding declaration}}% @@ -6101,19 +6484,27 @@ of the \grammarterm{identifier-list} as names\iref{basic.scope.declarative} of \defn{structured binding}{s}. -Let \cv{} denote the -\grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq}. First, a -variable with a unique name \tcode{e} is introduced. If the +Let \cv{} denote the \grammarterm{cv-qualifier}{s} in +the \grammarterm{decl-specifier-seq} and +\placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of +the \grammarterm{decl-specifier-seq} (if any). +First, a variable with a unique name \exposid{e} is introduced. If the \grammarterm{assignment-expression} in the \grammarterm{initializer} -has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, \tcode{e} -has type \cv{}~\tcode{A} and each element is copy-initialized or direct-initialized +has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, +\exposid{e} is defined by + +\begin{ncbnf} +\opt{attribute-specifier-seq} \placeholder{S} \cv{} \terminal{A} \exposid{e} \terminal{;} +\end{ncbnf} + +and each element is copy-initialized or direct-initialized from the corresponding element of the \grammarterm{assignment-expression} as specified by the form of the \grammarterm{initializer}. -Otherwise, \tcode{e} +Otherwise, \exposid{e} is defined as-if by \begin{ncbnf} -\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{e} initializer \terminal{;} +\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \exposid{e} initializer \terminal{;} \end{ncbnf} where @@ -6121,7 +6512,7 @@ the parts of the declaration other than the \grammarterm{declarator-id} are taken from the corresponding structured binding declaration. The type of the \grammarterm{id-expression} -\tcode{e} is called \tcode{E}. +\exposid{e} is called \tcode{E}. \begin{note} \tcode{E} is never a reference type\iref{expr.prop}. \end{note} @@ -6151,7 +6542,7 @@ \pnum Otherwise, if the \grammarterm{qualified-id} \tcode{std::tuple_size} -names a complete type, +names a complete class type with a member named \tcode{value}, the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression and @@ -6166,20 +6557,26 @@ that is a function template whose first template parameter is a non-type parameter, the initializer is -\tcode{e.get()}. Otherwise, the initializer is \tcode{get(e)}, +\tcode{\exposid{e}.get()}. Otherwise, the initializer is \tcode{get(\exposid{e})}, where \tcode{get} is looked up in the associated namespaces\iref{basic.lookup.argdep}. In either case, \tcode{get} is interpreted as a \grammarterm{template-id}. \begin{note} Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. \end{note} -In either case, \tcode{e} is an lvalue if the type of the entity \tcode{e} -is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ -designated by \tcode{std::tuple_element::type}, -variables are introduced with unique names $\tcode{r}_i$ -of type ``reference to $\tcode{T}_i$'' -initialized with the initializer~(\ref{dcl.init.ref}), -where the reference is an lvalue reference if the initializer is -an lvalue and an rvalue reference otherwise. +In either case, \exposid{e} is an lvalue if the type of the entity \exposid{e} +is an lvalue reference and an xvalue otherwise. +Given the type $\tcode{T}_i$ designated by +\tcode{std::tuple_element::type} and +the type $\tcode{U}_i$ designated by +either \tcode{$\tcode{T}_i$\&} or \tcode{$\tcode{T}_i$\&\&}, +where $\tcode{U}_i$ is an lvalue reference if +the initializer is an lvalue and an rvalue reference otherwise, +variables are introduced with unique names $\tcode{r}_i$ as follows: + +\begin{ncbnf} +\placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;} +\end{ncbnf} + Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ that refers to the object bound to $\tcode{r}_i$; the referenced type is $\tcode{T}_i$. @@ -6189,7 +6586,7 @@ all of \tcode{E}'s non-static data members shall be direct members of \tcode{E} or of the same base class of \tcode{E}, -well-formed when named as \tcode{e.\placeholder{name}} +well-formed when named as \tcode{\exposid{e}.\placeholder{name}} in the context of the structured binding, \tcode{E} shall not have an anonymous union member, and the number of elements in the \grammarterm{identifier-list} shall be @@ -6198,7 +6595,7 @@ $\tcode{m}_0$, $\tcode{m}_1$, $\tcode{m}_2, \dotsc$ (in declaration order), each \tcode{v}$_i$ is the -name of an lvalue that refers to the member \tcode{m}$_i$ of \tcode{e} and +name of an lvalue that refers to the member \tcode{m}$_i$ of \exposid{e} and whose type is \cv{}~$\tcode{T}_i$, where $\tcode{T}_i$ is the declared type of that member; the referenced type is \cv{}~$\tcode{T}_i$. The lvalue is a bit-field if that member is a bit-field. @@ -6249,9 +6646,9 @@ \begin{bnf} \nontermdef{enum-key}\br - \terminal{enum}\br - \terminal{enum class}\br - \terminal{enum struct} + \keyword{enum}\br + \keyword{enum} \keyword{class}\br + \keyword{enum} \keyword{struct} \end{bnf} \begin{bnf} @@ -6435,7 +6832,7 @@ For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, the values of the enumeration are the values representable by -a hypothetical integer types with minimal range exponent $M$ +a hypothetical integer type with minimal width $M$ such that all enumerators can be represented. The width of the smallest bit-field large enough to hold all the values of the enumeration type is $M$. @@ -6542,6 +6939,25 @@ the definition of a namespace can be split over several parts of one or more translation units. +\pnum +\begin{note} +A namespace name with external linkage is exported +if any of its \term{namespace-definition}{s} is exported, +or if it contains any +\grammarterm{export-declaration}{s}\iref{module.interface}. +A namespace is never attached to a module, +and never has module linkage +even if it is not exported. +\end{note} +\begin{example} +\begin{codeblock} +export module M; +namespace N1 {} // \tcode{N1} is not exported +export namespace N2 {} // \tcode{N2} is exported +namespace N3 { export int n; } // \tcode{N3} is exported +\end{codeblock} +\end{example} + \pnum The outermost declarative region of a translation unit is a namespace; see~\ref{basic.scope.namespace}. @@ -6565,23 +6981,23 @@ \begin{bnf} \nontermdef{named-namespace-definition}\br - \terminal{\opt{inline}} \terminal{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}} + \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{unnamed-namespace-definition}\br - \terminal{\opt{inline}} \terminal{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}} + \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{nested-namespace-definition}\br - \terminal{namespace} enclosing-namespace-specifier \terminal{::} \opt{\terminal{inline}} identifier \terminal{\{} namespace-body \terminal{\}} + \keyword{namespace} enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{enclosing-namespace-specifier}\br identifier\br - enclosing-namespace-specifier \terminal{::} \opt{\terminal{inline}} identifier + enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \end{bnf} \begin{bnf} @@ -6725,38 +7141,38 @@ replaced by \begin{ncsimplebnf} -\opt{\terminal{inline}} \terminal{namespace} \terminal{\uniquens} \terminal{\{ /* empty body */ \}}\br -\terminal{using namespace} \terminal{\uniquens} \terminal{;}\br -\terminal{namespace} \terminal{\uniquens} \terminal{\{} namespace-body \terminal{\}} +\opt{\keyword{inline}} \keyword{namespace} \exposid{unique} \terminal{\{ /* empty body */ \}}\br +\keyword{using} \keyword{namespace} \exposid{unique} \terminal{;}\br +\keyword{namespace} \exposid{unique} \terminal{\{} namespace-body \terminal{\}} \end{ncsimplebnf} where \tcode{inline} appears if and only if it appears in the \grammarterm{unnamed-namespace-definition} -and all occurrences of \tcode{\uniquens} in a translation unit are replaced by +and all occurrences of \exposid{unique} in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit. The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{unnamed-namespace-definition} -appertains to \tcode{\uniquens}. +appertains to \exposid{unique}. \begin{example} \begin{codeblock} -namespace { int i; } // \tcode{\uniquens::i} -void f() { i++; } // \tcode{\uniquens::i++} +namespace { int i; } // \tcode{\exposid{unique}::i} +void f() { i++; } // \tcode{\exposid{unique}::i++} namespace A { namespace { - int i; // \tcode{A::\uniquens::i} - int j; // \tcode{A::\uniquens::j} + int i; // \tcode{A::\exposid{unique}::i} + int j; // \tcode{A::\exposid{unique}::j} } - void g() { i++; } // \tcode{A::\uniquens::i++} + void g() { i++; } // \tcode{A::\exposid{unique}::i++} } using namespace A; void h() { - i++; // error: \tcode{\uniquens::i} or \tcode{A::\uniquens::i} - A::i++; // \tcode{A::\uniquens::i} - j++; // \tcode{A::\uniquens::j} + i++; // error: \tcode{\exposid{unique}::i} or \tcode{A::\exposid{unique}::i} + A::i++; // \tcode{A::\exposid{unique}::i} + j++; // \tcode{A::\exposid{unique}::j} } \end{codeblock} \end{example} @@ -6894,7 +7310,7 @@ \begin{bnf} \nontermdef{namespace-alias-definition}\br - \terminal{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} + \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} \end{bnf} \begin{bnf} @@ -6934,7 +7350,7 @@ \begin{bnf} \nontermdef{using-directive}\br - \opt{attribute-specifier-seq} \terminal{using namespace} \opt{nested-name-specifier} namespace-name \terminal{;} + \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} \opt{nested-name-specifier} namespace-name \terminal{;} \end{bnf} \pnum @@ -7145,7 +7561,7 @@ \begin{bnf} \nontermdef{using-declaration}\br - \terminal{using} using-declarator-list \terminal{;} + \keyword{using} using-declarator-list \terminal{;} \end{bnf} \begin{bnf} @@ -7156,7 +7572,7 @@ \begin{bnf} \nontermdef{using-declarator}\br - \terminal{\opt{typename}} nested-name-specifier unqualified-id + \opt{\keyword{typename}} nested-name-specifier unqualified-id \end{bnf} \pnum @@ -7639,7 +8055,7 @@ \begin{bnf} \nontermdef{asm-definition}\br - \opt{attribute-specifier-seq} \terminal{asm (} string-literal \terminal{) ;} + \opt{attribute-specifier-seq} \keyword{asm} \terminal{(} string-literal \terminal{) ;} \end{bnf} The \tcode{asm} declaration is conditionally-supported; its meaning is @@ -7678,8 +8094,8 @@ % \begin{bnf} \nontermdef{linkage-specification}\br - \terminal{extern} string-literal \terminal{\{} \opt{declaration-seq} \terminal{\}}\br - \terminal{extern} string-literal declaration + \keyword{extern} string-literal \terminal{\{} \opt{declaration-seq} \terminal{\}}\br + \keyword{extern} string-literal declaration \end{bnf} The \grammarterm{string-literal} indicates the required language linkage. @@ -7910,13 +8326,13 @@ \begin{bnf} \nontermdef{alignment-specifier}\br - \terminal{alignas (} type-id \opt{\terminal{...}} \terminal{)}\br - \terminal{alignas (} constant-expression \opt{\terminal{...}} \terminal{)} + \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br + \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)} \end{bnf} \begin{bnf} \nontermdef{attribute-using-prefix}\br - \terminal{using} attribute-namespace \terminal{:} + \keyword{using} attribute-namespace \terminal{:} \end{bnf} \begin{bnf} @@ -8069,10 +8485,7 @@ An \grammarterm{alignment-specifier} may also be applied to the declaration of a class (in an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} or -\grammarterm{class-head}\iref{class}, respectively) and to the -declaration of an enumeration (in an -\grammarterm{opaque-enum-declaration} or \grammarterm{enum-head}, -respectively\iref{dcl.enum}). +\grammarterm{class-head}\iref{class}, respectively). An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}. \pnum @@ -8249,16 +8662,16 @@ \begin{bnf} \nontermdef{contract-attribute-specifier}\br - \terminal{[} \terminal{[} \terminal{expects} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br - \terminal{[} \terminal{[} \terminal{ensures} \opt{contract-level} \opt{identifier} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br - \terminal{[} \terminal{[} \terminal{assert} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]} + \terminal{[} \terminal{[} \keyword{expects} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} \keyword{ensures} \opt{contract-level} \opt{identifier} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} \keyword{assert} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]} \end{bnf} \begin{bnf} \nontermdef{contract-level}\br - \terminal{default}\br - \terminal{audit}\br - \terminal{axiom} + \keyword{default}\br + \keyword{audit}\br + \keyword{axiom} \end{bnf} @@ -8283,6 +8696,9 @@ The attribute may be applied to the function type of a function declaration. A postcondition may introduce an identifier to represent the glvalue result or the prvalue result object of the function. +When the declared return type of a non-templated function +contains a placeholder type, +the optional \grammarterm{identifier} shall only be present in a definition. \begin{example} \begin{codeblock} int f(char * c) @@ -8290,6 +8706,9 @@ int g(double * p) [[ensures audit res: res != 0 && p != nullptr && *p <= 0.0]]; + +auto h(int x) + [[ensures res: true]]; // error: cannot name the return value \end{codeblock} \end{example} @@ -8403,7 +8822,10 @@ \pnum The predicate of a contract condition has the same semantic restrictions as if it appeared as the first \grammarterm{expression-statement} -in the body of the function it applies to. +in the body of the function it applies to, +except that the return type of the function is +known in a contract condition appertaining to its definition, +even if the return type contains a placeholder type. \pnum A precondition is checked by evaluating its predicate @@ -8442,7 +8864,7 @@ \pnum If a postcondition odr-uses\iref{basic.def.odr} -a parameter in its predicate +a non-reference parameter in its predicate and the function body makes direct or indirect modifications of the value of that parameter, the behavior is undefined. @@ -8454,8 +8876,8 @@ return ++x; // undefined behavior } -int g(int * p) - [[ensures r: p != nullptr]] +void g(int * p) + [[ensures: p != nullptr]] { *p = 42; // OK, \tcode{p} is not modified } @@ -8780,15 +9202,19 @@ \pnum The attribute may be applied to the declaration of a class, -a \grammarterm{typedef-name}, a variable, a non-static data member, +a \grammarterm{typedef-name}, +a variable (including a structured binding declaration), +a non-static data member, a function, an enumeration, or an enumerator. \pnum -\begin{note} -For an entity marked \tcode{maybe_unused}, implementations -should not emit a warning that the entity is unused, or -that the entity is used despite the presence of the attribute. -\end{note} +For an entity marked \tcode{maybe_unused}, +implementations should not emit a warning +that the entity or its structured bindings (if any) +are used or unused. +For a structured binding declaration not marked \tcode{maybe_unused}, +implementations should not emit such a warning unless +all of its structured bindings are unused. \pnum A name or entity declared without the \tcode{maybe_unused} attribute diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 29b67330c1..1cc9dd3e3f 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -100,11 +100,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{logic_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -116,11 +111,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{logic_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -151,11 +141,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{domain_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -167,11 +152,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{domain_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -201,11 +181,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{invalid_argument}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -217,11 +192,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{invalid_argument}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -253,11 +223,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{length_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -269,11 +234,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{length_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -305,11 +265,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{out_of_range}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -321,11 +276,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{out_of_range}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -356,11 +306,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{runtime_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -372,11 +317,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{runtime_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -407,11 +347,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{range_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -423,11 +358,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{range_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -457,11 +387,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{overflow_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -473,11 +398,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{overflow_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -507,11 +427,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{underflow_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. @@ -523,11 +438,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{underflow_error}. - \pnum \ensures \tcode{strcmp(what(), what_arg) == 0}. @@ -767,7 +677,7 @@ Implementations should leave the error states provided by other libraries unchanged. -\rSec2[system_error.syn]{Header \tcode{} synopsis} +\rSec2[system.error.syn]{Header \tcode{} synopsis} \indexhdr{system_error}% \indexlibrary{\idxcode{error_category}}% \indexlibrary{\idxcode{error_code}}% @@ -939,6 +849,8 @@ such type. \end{note} \indexlibrary{\idxcode{error_category}}% +\indexlibrary{\idxcode{error_category}!constructor}% +\indexlibrary{\idxcode{error_category}!destructor}% \indexlibrary{\idxcode{generic_category}}% \indexlibrary{\idxcode{system_category}}% \begin{codeblock} @@ -967,16 +879,6 @@ \rSec3[syserr.errcat.virtuals]{Virtual members} -\indexlibrary{\idxcode{error_category}!destructor}% -\begin{itemdecl} -virtual ~error_category(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Destroys an object of class \tcode{error_category}. -\end{itemdescr} - \indexlibrarymember{name}{error_category}% \begin{itemdecl} virtual const char* name() const noexcept = 0; @@ -1030,16 +932,6 @@ \rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} -\indexlibrary{\idxcode{error_category}!constructor}% -\begin{itemdecl} -constexpr error_category() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{error_category}. -\end{itemdescr} - \indexlibrarymember{operator==}{error_category}% \begin{itemdecl} bool operator==(const error_category& rhs) const noexcept; @@ -1211,9 +1103,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{error_code}. - \pnum \ensures \tcode{val_ == 0} and \tcode{cat_ == \&system_category()}. \end{itemdescr} @@ -1224,9 +1113,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{error_code}. - \pnum \ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} @@ -1239,14 +1125,10 @@ \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_code}. +\constraints \tcode{is_error_code_enum_v} is \tcode{true}. \pnum \ensures \tcode{*this == make_error_code(e)}. - -\pnum -\remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak -\tcode{is_error_code_enum_v} is \tcode{true}. \end{itemdescr} \rSec3[syserr.errcode.modifiers]{Modifiers} @@ -1269,14 +1151,13 @@ \begin{itemdescr} \pnum -\ensures \tcode{*this == make_error_code(e)}. +\constraints \tcode{is_error_code_enum_v} is \tcode{true}. \pnum -\returns \tcode{*this}. +\ensures \tcode{*this == make_error_code(e)}. \pnum -\remarks \raggedright This operator shall not participate in overload resolution unless\linebreak -\tcode{is_error_code_enum_v} is \tcode{true}. +\returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{clear}{error_code}% @@ -1363,7 +1244,7 @@ \begin{itemdescr} \pnum \effects -As if by: \tcode{os << ec.category().name() << ':' << ec.value();} +Equivalent to: \tcode{return os << ec.category().name() << ':' << ec.value();} \end{itemdescr} @@ -1414,9 +1295,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{error_condition}. - \pnum \ensures \tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}. \end{itemdescr} @@ -1427,9 +1305,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{error_condition}. - \pnum \ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} @@ -1442,14 +1317,10 @@ \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_condition}. +\constraints \tcode{is_error_condition_enum_v} is \tcode{true}. \pnum \ensures \tcode{*this == make_error_condition(e)}. - -\pnum -\remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak -\tcode{is_error_condition_enum_v} is \tcode{true}. \end{itemdescr} @@ -1473,14 +1344,13 @@ \begin{itemdescr} \pnum -\ensures \tcode{*this == make_error_condition(e)}. +\constraints \tcode{is_error_condition_enum_v} is \tcode{true}. \pnum -\returns \tcode{*this}. +\ensures \tcode{*this == make_error_condition(e)}. \pnum -\remarks \raggedright This operator shall not participate in overload resolution unless\linebreak -\tcode{is_error_condition_enum_v} is \tcode{true}. +\returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{clear}{error_condition}% @@ -1699,11 +1569,8 @@ \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\ensures \tcode{code() == ec} and -\tcode{string(what()).find(what_arg) != string::npos}. +\ensures \tcode{code() == ec} and\newline +\tcode{string_view(what()).find(what_arg.c_str()) != string_view::npos}. \end{itemdescr} \indexlibrary{\idxcode{system_error}!constructor}% @@ -1712,12 +1579,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{system_error}. - \pnum \ensures \tcode{code() == ec} and -\tcode{string(what()).find(what_arg) != string::npos}. +\tcode{string_view(what()).find(what_arg) != string_view::npos}. \end{itemdescr} \indexlibrary{\idxcode{system_error}!constructor}% @@ -1726,9 +1590,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{system_error}. - \pnum \ensures \tcode{code() == ec}. \end{itemdescr} @@ -1739,12 +1600,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{system_error}. - \pnum \ensures \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak -\tcode{string(what()).find(what_arg) != string::npos}. +\tcode{string_view(what()).find(what_arg.c_str()) != string_view::npos}. \end{itemdescr} \indexlibrary{\idxcode{system_error}!constructor}% @@ -1753,12 +1611,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{system_error}. - \pnum \ensures \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak -\tcode{string(what()).find(what_arg) != string::npos}. +\tcode{string_view(what()).find(what_arg) != string_view::npos}. \end{itemdescr} \indexlibrary{\idxcode{system_error}!constructor}% @@ -1767,9 +1622,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{system_error}. - \pnum \ensures \tcode{code() == error_code(ev, ecat)}. \end{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index 22947b9438..6a53134326 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -365,12 +365,12 @@ \indextext{unwinding!stack}% As control passes from the point where an exception is thrown to a handler, -destructors are invoked by a process, specified in this subclause, called -\defn{stack unwinding}. +objects with automatic storage duration are destroyed by a process, +specified in this subclause, called \defn{stack unwinding}. \pnum -The destructor is invoked for each automatic object of class type constructed, -but not yet destroyed, +Each object with automatic storage duration is destroyed if it has been +constructed, but not yet destroyed, since the try block was entered. If an exception is thrown during the destruction of temporaries or local variables for a \tcode{return} statement\iref{stmt.return}, @@ -414,6 +414,12 @@ and whose destructor has not yet begun execution, except that in the case of destruction, the variant members of a union-like class are not destroyed. +\begin{note} +If such an object has a reference member +that extends the lifetime of a temporary object, +this ends the lifetime of the reference member, +so the lifetime of the temporary object is effectively not extended. +\end{note} The subobjects are destroyed in the reverse order of the completion of their construction. Such destruction is sequenced before entering a handler of the \grammarterm{function-try-block} of the constructor or destructor, @@ -882,7 +888,9 @@ is potentially-throwing if and only if any of the destructors for any of its potentially constructed subobjects -is potentially throwing. +is potentially-throwing or +the destructor is virtual and the destructor of any virtual base class +is potentially-throwing. \pnum The exception specification for an implicitly-declared assignment operator, diff --git a/source/expressions.tex b/source/expressions.tex index 30f4eb6cf0..6db8a8a545 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -100,7 +100,7 @@ since if the values for \tcode{a} and \tcode{b} were, respectively, -32754 and -15, the sum \tcode{a + b} would produce an exception while the original expression would not; nor can the expression be rewritten -either as +as either \begin{codeblock} a = ((a + 32765) + b); \end{codeblock} @@ -284,32 +284,26 @@ \pnum If a program attempts to access the stored value of an object through a glvalue -of other than one of the following types the behavior is +whose type is not similar\iref{conv.qual} to +one of the following types the behavior is undefined:\footnote{The intent of this list is to specify those circumstances in which an object may or may not be aliased.} \begin{itemize} \item the dynamic type of the object, -\item a cv-qualified version of the dynamic type of the object, - -\item a type similar (as defined in~\ref{conv.qual}) to the dynamic type -of the object, - \item a type that is the signed or unsigned type corresponding to the -dynamic type of the object, - -\item a type that is the signed or unsigned type corresponding to a -cv-qualified version of the dynamic type of the object, - -\item an aggregate or union type that includes one of the aforementioned types among its -elements or non-static data members (including, recursively, an element or non-static data member of a -subaggregate or contained union), - -\item a type that is a (possibly cv-qualified) base class type of the dynamic type of -the object, +dynamic type of the object, or \item a \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} type. \end{itemize} +If a program invokes +a defaulted copy/move constructor or copy/move assignment operator +for a union of type \tcode{U} with a glvalue argument +that does not denote an object of type \cv{}~\tcode{U} within its lifetime, +the behavior is undefined. +\begin{note} +Unlike in C, \Cpp{} has no accesses of class type. +\end{note} \rSec2[expr.type]{Type} @@ -368,7 +362,7 @@ \item if \tcode{T1} or \tcode{T2} is ``pointer to \cvqual{cv1} \tcode{void}'' and the -other type is ``pointer to \cvqual{cv2} T'', +other type is ``pointer to \cvqual{cv2} \tcode{T}'', where \tcode{T} is an object type or \tcode{void}, ``pointer to \cvqual{cv12} \tcode{void}'', where \cvqual{cv12} is the union of \cvqual{cv1} and \cvqual{cv2}; @@ -386,8 +380,23 @@ respectively; \item -if \tcode{T1} is ``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U1}'' and \tcode{T2} is -``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U2}'' where \tcode{C1} is +if \tcode{T1} or \tcode{T2} is +``pointer to member of \tcode{C1} of type function'', +the other type is +``pointer to member of \tcode{C2} of type \tcode{noexcept} function'', and +\tcode{C1} is reference-related to \tcode{C1} or +\tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, +where the function types are otherwise the same, +``pointer to member of \tcode{C2} of type function'' or +``pointer to member of \tcode{C1} of type function'', respectively; + +\item +if \tcode{T1} is +``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U}'' and +\tcode{T2} is +``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U}'', +for some non-function type \tcode{U}, +where \tcode{C1} is reference-related to \tcode{C2} or \tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, the cv-combined type of \tcode{T2} and \tcode{T1} or the cv-combined type of \tcode{T1} and \tcode{T2}, respectively; @@ -713,7 +722,7 @@ $\cv{}_i$ and $P_i$ such that \tcode{T} is \begin{indented} -``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n > 0$, +``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n \geq 0$, \end{indented} where each $\cv{}_i$ is a set of cv-qualifiers\iref{basic.type.qualifier}, and @@ -825,9 +834,8 @@ \pnum \indextext{type!underlying!enumeration}% A prvalue of an unscoped enumeration type whose underlying type is not -fixed\iref{dcl.enum} can be converted to a prvalue of the first of the following -types that can represent all the values of the enumeration (i.e., the values in the -range $b_\text{min}$ to $b_\text{max}$ as described in~\ref{dcl.enum}): \tcode{int}, +fixed can be converted to a prvalue of the first of the following +types that can represent all the values of the enumeration\iref{dcl.enum}: \tcode{int}, \tcode{unsigned int}, \tcode{long int}, \tcode{unsigned long int}, \tcode{long long int}, or \tcode{unsigned long long int}. If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped @@ -890,7 +898,7 @@ \indextext{conversion!to signed}% Otherwise, the result is the unique value of the destination type that is congruent to the source integer modulo $2^N$, -where $N$ is the range exponent of the destination type. +where $N$ is the width of the destination type. \pnum The conversions allowed as integral promotions are excluded from the set @@ -973,7 +981,7 @@ \pnum A prvalue of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} -is a class type, can be converted to a prvalue of type ``pointer to +is a complete class type, can be converted to a prvalue of type ``pointer to \cv{} \tcode{B}'', where \tcode{B} is a base class\iref{class.derived} of \tcode{D}. If \tcode{B} is an inaccessible\iref{class.access} or @@ -1005,8 +1013,8 @@ A prvalue of type ``pointer to member of \tcode{B} of type \cv{} \tcode{T}'', where \tcode{B} is a class type, can be converted to a prvalue of type ``pointer to member of \tcode{D} of type \cv{} -\tcode{T}'', where \tcode{D} is a derived class\iref{class.derived} -of \tcode{B}. If \tcode{B} is an +\tcode{T}'', where \tcode{D} is a complete class derived\iref{class.derived} +from \tcode{B}. If \tcode{B} is an inaccessible\iref{class.access}, ambiguous\iref{class.member.lookup}, or virtual\iref{class.mi} base class of \tcode{D}, or a base class of a virtual base class of @@ -1132,7 +1140,7 @@ \begin{bnf} \nontermdef{primary-expression}\br literal\br - \terminal{this}\br + \keyword{this}\br \terminal{(} expression \terminal{)}\br id-expression\br lambda-expression\br @@ -1406,7 +1414,7 @@ % \begin{bnf} \nontermdef{qualified-id}\br - nested-name-specifier \opt{\terminal{template}} unqualified-id + nested-name-specifier \opt{\keyword{template}} unqualified-id \end{bnf} \indextext{operator!scope resolution}% @@ -1419,7 +1427,7 @@ namespace-name \terminal{::}\br decltype-specifier \terminal{::}\br nested-name-specifier identifier \terminal{::}\br - nested-name-specifier \opt{\terminal{template}} simple-template-id \terminal{::} + nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{::} \end{bnf} \pnum @@ -1475,9 +1483,13 @@ \grammarterm{unqualified-id} is a \grammarterm{conversion-function-id}, its \grammarterm{conversion-type-id} -shall denote the same type in both the context in which the entire -\grammarterm{qualified-id} occurs and in the context of the class denoted -by the \grammarterm{nested-name-specifier}. +is first looked up in the class denoted by +the \grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} and +the name, if found, is used. +Otherwise, it is looked up in the context in which +the entire \grammarterm{qualified-id} occurs. +In each of these lookups, only names that denote types or +templates whose specializations are types are considered. \rSec3[expr.prim.id.dtor]{Destruction} @@ -1766,11 +1778,14 @@ has a non-throwing exception specification. The value returned by this conversion function is the address of a function \tcode{F} that, when invoked, -has the same effect as invoking the closure type's function call operator. +has the same effect as invoking the closure type's function call operator +on a default-constructed instance of the closure type. \tcode{F} is a constexpr function if the function call operator is a constexpr function and is an immediate function if the function call operator is an immediate function. + +\pnum For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a conversion function template to pointer to function. The conversion function template has the same invented @@ -1835,9 +1850,11 @@ The value returned by any given specialization of this conversion function template is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator -template specialization. +template specialization on a default-constructed instance of the closure type. \tcode{F} is a constexpr function -if the corresponding specialization is a constexpr function. +if the corresponding specialization is a constexpr function and +\tcode{F} is an immediate function +if the function call operator template specialization is an immediate function. \begin{note} This will result in the implicit instantiation of the generic lambda's body. The instantiated generic lambda's return type and parameter types shall match @@ -1948,7 +1965,7 @@ \nontermdef{simple-capture}\br identifier\br \terminal{\&} identifier\br - \terminal{this}\br + \keyword{this}\br \terminal{* this} \end{bnf} @@ -2145,12 +2162,11 @@ An entity is \defn{captured} if it is captured explicitly or implicitly. An entity captured by a \grammarterm{lambda-expression} is odr-used\iref{basic.def.odr} in the scope containing the \grammarterm{lambda-expression}. -If a \grammarterm{lambda-expression} -explicitly captures an entity that is not odr-usable -or -captures a structured binding (explicitly or implicitly), -the program is -ill-formed. +\begin{note} +As a consequence, if a \grammarterm{lambda-expression} +explicitly captures an entity that is not odr-usable, +the program is ill-formed\iref{basic.def.odr}. +\end{note} \begin{example} \indextext{Bond!James Bond}% \begin{codeblock} @@ -2200,8 +2216,17 @@ \end{example} \pnum -A \grammarterm{lambda-expression} appearing in a default argument shall not -implicitly or explicitly capture any entity. +\begin{note} +Because local entities are not +odr-usable within a default argument\iref{basic.def.odr}, +a \grammarterm{lambda-expression} appearing in a default argument +cannot implicitly or explicitly capture any local entity. +Such a \grammarterm{lambda-expression} +can still have an \grammarterm{init-capture} if +any full-expression in its \grammarterm{initializer} +satisfies the constraints of an expression appearing in +a default argument\iref{dcl.fct.default}. +\end{note} \begin{example} \begin{codeblock} void f2() { @@ -2211,6 +2236,8 @@ void g3(int = ([=]{ return i; })()); // ill-formed void g4(int = ([=]{ return 0; })()); // OK void g5(int = ([]{ return sizeof i; })()); // OK + void g6(int = ([x=1]{ return x; })()); // OK + void g7(int = ([x=i]{ return x; })()); // ill-formed } \end{codeblock} \end{example} @@ -2274,7 +2301,8 @@ static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4); \end{codeblock} \end{example} -A bit-field or a member of an anonymous union shall not be captured by reference. +A bit-field or a member of an anonymous union +shall not be captured by reference. \pnum An \grammarterm{id-expression} within @@ -2453,7 +2481,7 @@ \begin{bnf} \nontermdef{requires-expression}\br - \terminal{requires} \opt{requirement-parameter-list} requirement-body + \keyword{requires} \opt{requirement-parameter-list} requirement-body \end{bnf} \begin{bnf} @@ -2598,7 +2626,7 @@ \begin{bnf} \nontermdef{type-requirement}\br - \terminal{typename} \opt{nested-name-specifier} type-name \terminal{;} + \keyword{typename} \opt{nested-name-specifier} type-name \terminal{;} \end{bnf} \pnum @@ -2629,7 +2657,7 @@ \begin{bnf} \nontermdef{compound-requirement}\br - \terminal{\{} expression \terminal{\}} \opt{\terminal{noexcept}} \opt{return-type-requirement} \terminal{;} + \terminal{\{} expression \terminal{\}} \opt{\keyword{noexcept}} \opt{return-type-requirement} \terminal{;} \end{bnf} \begin{bnf} @@ -2738,7 +2766,7 @@ \begin{bnf} \nontermdef{nested-requirement}\br - \terminal{requires} constraint-expression \terminal{;} + \keyword{requires} constraint-expression \terminal{;} \end{bnf} \pnum @@ -2796,12 +2824,12 @@ postfix-expression \opt{\terminal{-> template}} id-expression\br postfix-expression \terminal{++}\br postfix-expression \terminal{-{-}}\br - \terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{typeid (} expression \terminal{)}\br - \terminal{typeid (} type-id \terminal{)} + \keyword{dynamic_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br + \keyword{static_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br + \keyword{reinterpret_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br + \keyword{const_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br + \keyword{typeid} \terminal{(} expression \terminal{)}\br + \keyword{typeid} \terminal{(} type-id \terminal{)} \end{bnf} \begin{bnf} @@ -2860,10 +2888,10 @@ constitute the arguments to the function. The postfix expression shall have function type or function pointer type. For a call to a non-member function or to a static member function, -the postfix expression shall be either an lvalue that refers to a +the postfix expression shall either be an lvalue that refers to a function (in which case the function-to-pointer standard conversion\iref{conv.func} is suppressed on the postfix expression), -or it shall have function pointer type. +or have function pointer type. \pnum For a call to a non-static member function, @@ -3361,15 +3389,13 @@ the result is \tcode{v} (converted if necessary). -\pnum -If the value of \tcode{v} is a null pointer value in the pointer case, -the result is the null pointer value of type \tcode{T}. - \pnum If \tcode{T} is ``pointer to \cvqual{cv1} \tcode{B}'' and \tcode{v} has type ``pointer to \cvqual{cv2} \tcode{D}'' such that \tcode{B} is a base class of \tcode{D}, the result is a pointer to the unique \tcode{B} -subobject of the \tcode{D} object pointed to by \tcode{v}. Similarly, if +subobject of the \tcode{D} object pointed to by \tcode{v}, or +a null pointer value if \tcode{v} is a null pointer value. +Similarly, if \tcode{T} is ``reference to \cvqual{cv1} \tcode{B}'' and \tcode{v} has type \cvqual{cv2} \tcode{D} such that \tcode{B} is a base class of \tcode{D}, the result is the unique \tcode{B} subobject of the \tcode{D} @@ -3395,6 +3421,9 @@ Otherwise, \tcode{v} shall be a pointer to or a glvalue of a polymorphic type\iref{class.virtual}. +\pnum +If \tcode{v} is a null pointer value, the result is a null pointer value. + \pnum If \tcode{T} is ``pointer to \cv{} \tcode{void}'', then the result is a pointer to the most derived object pointed to by \tcode{v}. @@ -3713,7 +3742,8 @@ \indextext{cast!derived class}% A prvalue of type ``pointer to \cvqual{cv1} \tcode{B}'', where \tcode{B} is a class type, can be converted to a prvalue of type ``pointer to -\cvqual{cv2} \tcode{D}'', where \tcode{D} is a class derived\iref{class.derived} +\cvqual{cv2} \tcode{D}'', +where \tcode{D} is a complete class derived\iref{class.derived} from \tcode{B}, if \cvqual{cv2} is the same cv-qualification as, or greater cv-qualification than, \cvqual{cv1}. @@ -3732,8 +3762,9 @@ \indextext{cast!pointer-to-member}% A prvalue of type ``pointer to member of \tcode{D} of type \cvqual{cv1} \tcode{T}'' can be converted to a prvalue of type ``pointer to member of -\tcode{B} of type \cvqual{cv2} \tcode{T}'', where \tcode{B} is a base -class\iref{class.derived} of \tcode{D}, +\tcode{B} of type \cvqual{cv2} \tcode{T}'', where +\tcode{D} is a complete class type and +\tcode{B} is a base class\iref{class.derived} of \tcode{D}, if \cvqual{cv2} is the same cv-qualification as, or greater cv-qualification than, \cvqual{cv1}.\footnote{Function types (including those used in pointer-to-member-function @@ -4063,13 +4094,14 @@ \begin{bnf} \nontermdef{unary-expression}\br postfix-expression\br + unary-operator cast-expression\br \terminal{++} cast-expression\br \terminal{-{-}} cast-expression\br - unary-operator cast-expression\br - \terminal{sizeof} unary-expression\br - \terminal{sizeof (} type-id \terminal{)}\br - \terminal{sizeof ...} \terminal{(} identifier \terminal{)}\br - \terminal{alignof (} type-id \terminal{)}\br + await-expression\br + \keyword{sizeof} unary-expression\br + \keyword{sizeof} \terminal{(} type-id \terminal{)}\br + \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br + \keyword{alignof} \terminal{(} type-id \terminal{)}\br noexcept-expression\br new-expression\br delete-expression @@ -4265,6 +4297,189 @@ For postfix increment and decrement, see~\ref{expr.post.incr}. \end{note} +\rSec3[expr.await]{Await} +\indextext{expression!await}% +\indextext{\idxcode{co_await}}% + +\pnum +The \tcode{co_await} expression is used to suspend evaluation of a +coroutine\iref{dcl.fct.def.coroutine} while awaiting completion of +the computation represented by the operand expression. + +\begin{bnf} +\nontermdef{await-expression}\br + \terminal{co_await} cast-expression +\end{bnf} + +\pnum +An \grammarterm{await-expression} shall appear only in a potentially-evaluated +expression within the \grammarterm{compound-statement} of a +\grammarterm{function-body} outside of a \grammarterm{handler}\iref{except}. +In a \grammarterm{declaration-statement} or in the +\grammarterm{simple-declaration} (if any) +of a \grammarterm{for-init-statement}, an \grammarterm{await-expression} +shall appear only in an \grammarterm{initializer} of that +\grammarterm{declaration-statement} or \grammarterm{simple-declaration}. +An \grammarterm{await-expression} shall not appear in a +default argument\iref{dcl.fct.default}. +An \grammarterm{await-expression} shall not appear in the initializer of +a block-scope variable with static or thread storage duration. +A context within a function where an \grammarterm{await-expression} can appear +is called a \term{suspension context} of the function. + +\pnum +Evaluation of an \grammarterm{await-expression} involves the following +auxiliary types, expressions, and objects: + +\begin{itemize} +\item +\placeholder{p} is an lvalue naming the promise +object\iref{dcl.fct.def.coroutine} +of the enclosing coroutine and \tcode{P} is the type of that object. + +\item \placeholder{a} is the \grammarterm{cast-expression} if +the \grammarterm{await-expression} was implicitly produced by a +\grammarterm{yield-expression}\iref{expr.yield}, an initial suspend point, +or a final suspend point\iref{dcl.fct.def.coroutine}. +Otherwise, the \grammarterm{unqualified-id} \tcode{await_transform} is +looked up within the scope of \tcode{P} by class member access +lookup\iref{basic.lookup.classref}, +and if this lookup finds at least one declaration, then \placeholder{a} is +\mbox{\placeholder{p}\tcode{.await_transform(}\grammarterm{cast-expression}\tcode{)}}; +otherwise, \placeholder{a} is the \grammarterm{cast-expression}. + +\item +\placeholder{o} is determined by enumerating the applicable +\tcode{operator co_await} functions for an argument +\placeholder{a}\iref{over.match.oper}, and choosing the best one through +overload resolution\iref{over.match}. If overload resolution is ambiguous, +the program is ill-formed. +If no viable functions are found, \placeholder{o} is \placeholder{a}. +Otherwise, \placeholder{o} is a call to the selected function +with the argument \placeholder{a}. +If \placeholder{o} would be a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. + +\item +\placeholder{e} is an lvalue +referring to the result of evaluating +the (possibly-converted) \placeholder{o}. + +\item +% FIXME: h needs to be an expression so we can use it as an argument +% to await_suspend. What should its value category be? +% Don't forget to remove "and objects" from the intro sentence when +% this is fixed. +\placeholder{h} is an object of type +\tcode{std::coroutine_handle

} +referring to the enclosing coroutine. + +\item +\placeholder{await-ready} is the expression +\placeholder{e}\tcode{.await_ready()}, +contextually converted to \tcode{bool}. + +\item +\placeholder{await-suspend} is the expression +\placeholder{e}\tcode{.await_suspend(}\placeholder{h}\tcode{)}, +which shall be a prvalue of type \tcode{void}, \tcode{bool}, or +\tcode{std::coroutine_handle} for some type \tcode{Z}. + +\item +\placeholder{await-resume} is the expression +\placeholder{e}\tcode{.await_resume()}. +\end{itemize} + +\pnum +The \grammarterm{await-expression} has the same type and value category +as the \placeholder{await-resume} expression. + +\pnum +The \grammarterm{await-expression} evaluates +the (possibly-converted) \placeholder{o} expression and +the \placeholder{await-ready} expression, then: +\begin{itemize} +\item +If the result of \placeholder{await-ready} is \tcode{false}, +the coroutine is considered suspended. +Then: +\begin{itemize} +\item +If the type of \placeholder{await-suspend} +is \tcode{std::coroutine_handle}, +\placeholder{await-suspend}\tcode{.resume()} is evaluated. +\begin{note} +This resumes the coroutine referred to +by the result of \placeholder{await-suspend}. +Any number of coroutines may be successively resumed in this fashion, +eventually returning control flow to the current coroutine caller or +resumer\iref{dcl.fct.def.coroutine}. +\end{note} + +\item +Otherwise, if the type of \placeholder{await-suspend} +is \tcode{bool}, +\placeholder{await-suspend} is evaluated, +and the coroutine is resumed if the result is \tcode{false}. + +\item +Otherwise, \placeholder{await-suspend} is evaluated. +\end{itemize} +If the evaluation of \placeholder{await-suspend} +exits via an exception, the exception is caught, +the coroutine is resumed, and the exception is immediately +re-thrown\iref{except.throw}. Otherwise, control flow returns +to the current coroutine caller or resumer\iref{dcl.fct.def.coroutine} +without exiting any scopes\iref{stmt.jump}. + +\item +If the result of \placeholder{await-ready} is \tcode{true}, +or when the coroutine is resumed, +the \placeholder{await-resume} expression is evaluated, and +its result is the result of the \grammarterm{await-expression}. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +template +struct my_future { + @\commentellip@ + bool await_ready(); + void await_suspend(std::coroutine_handle<>); + T await_resume(); +}; + +template +auto operator co_await(std::chrono::duration d) { + struct awaiter { + std::chrono::system_clock::duration duration; + @\commentellip@ + awaiter(std::chrono::system_clock::duration d) : duration(d) {} + bool await_ready() const { return duration.count() <= 0; } + void await_resume() {} + void await_suspend(std::coroutine_handle<> h) { @\commentellip@ } + }; + return awaiter{d}; +} + +using namespace std::chrono; + +my_future h(); + +my_future g() { + std::cout << "just about go to sleep...\n"; + co_await 10ms; + std::cout << "resumed\n"; + co_await h(); +} + +auto f(int x = co_await h()); // error: \grammarterm{await-expression} outside of function suspension context +int a[] = { co_await h() }; // error: \grammarterm{await-expression} outside of function suspension context + +\end{codeblock} +\end{example} + \rSec3[expr.sizeof]{Sizeof} \pnum @@ -4300,7 +4515,7 @@ \pnum \indextext{reference!\idxcode{sizeof}}% -When applied to a reference or a reference type, the result is the size +When applied to a reference type, the result is the size of the referenced type. \indextext{class object!\idxcode{sizeof}}% When applied to a class, the result is the number of bytes in an object @@ -4318,10 +4533,6 @@ array. This implies that the size of an array of \term{n} elements is \term{n} times the size of an element. -\pnum -The \tcode{sizeof} operator can be applied to a pointer to a function, -but shall not be applied directly to a function. - \pnum The lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and @@ -4383,8 +4594,8 @@ \begin{bnf} \nontermdef{new-expression}\br - \opt{\terminal{::}} \terminal{new} \opt{new-placement} new-type-id \opt{new-initializer} \br - \opt{\terminal{::}} \terminal{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer} + \opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer} \br + \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer} \end{bnf} \indextext{\idxcode{new}!storage allocation}% @@ -4407,7 +4618,7 @@ \begin{bnf} \nontermdef{noptr-new-declarator}\br - \terminal{[} expression \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{[} \opt{expression} \terminal{]} \opt{attribute-specifier-seq}\br noptr-new-declarator \terminal{[} constant-expression \terminal{]} \opt{attribute-specifier-seq} \end{bnf} @@ -4521,9 +4732,6 @@ \grammarterm{noptr-new-declarator} shall be a converted constant expression\iref{expr.const} of type \tcode{std::size_t} and shall evaluate to a strictly positive value. -\indextext{\idxcode{new}}% -The \grammarterm{expression} in a \grammarterm{noptr-new-declarator} is -implicitly converted to \tcode{std::size_t}. \begin{example} Given the definition \tcode{int n = 42}, \tcode{new float[n][5]} is well-formed (because \tcode{n} is the @@ -4533,9 +4741,20 @@ \end{example} \pnum +If the \grammarterm{type-id} or \grammarterm{new-type-id} +denotes an array type of unknown bound\iref{dcl.array}, +the \grammarterm{new-initializer} shall not be omitted; +the allocated object is an array with \tcode{n} elements, +where \tcode{n} is determined from the number of initial elements +supplied in +the \grammarterm{new-initializer}~(\ref{dcl.init.aggr}, \ref{dcl.init.string}). + +\pnum +\indextext{\idxcode{new}}% +If the \grammarterm{expression} in a \grammarterm{noptr-new-declarator} +is present, it is implicitly converted to \tcode{std::size_t}. \indextext{function!allocation}% -The \grammarterm{expression} in a \grammarterm{noptr-new-declarator} is -erroneous if: +The \grammarterm{expression} is erroneous if: \begin{itemize} \item @@ -4917,8 +5136,8 @@ \begin{bnf} \nontermdef{delete-expression}\br - \opt{\terminal{::}} \terminal{delete} cast-expression\br - \opt{\terminal{::}} \terminal{delete [ ]} cast-expression + \opt{\terminal{::}} \keyword{delete} cast-expression\br + \opt{\terminal{::}} \keyword{delete} \terminal{[ ]} cast-expression \end{bnf} The first alternative is a @@ -5178,7 +5397,7 @@ \begin{bnf} \nontermdef{noexcept-expression}\br - \terminal{noexcept} \terminal{(} expression \terminal{)} + \keyword{noexcept} \terminal{(} expression \terminal{)} \end{bnf} \pnum @@ -5572,12 +5791,12 @@ left operand. \indextext{left shift!undefined}% The behavior is undefined if the right operand is negative, or greater -than or equal to the range exponent of the promoted left operand. +than or equal to the width of the promoted left operand. \pnum The value of \tcode{E1 << E2} is the unique value congruent to $\tcode{E1} \times 2^\tcode{E2}$ modulo $2^N$, -where $N$ is the range exponent of the type of the result. +where $N$ is the width of the type of the result. \begin{note} \tcode{E1} is left-shifted \tcode{E2} bit positions; vacated bits are zero-filled. @@ -5893,9 +6112,11 @@ \end{itemize} \pnum -If at least one of the operands is a pointer to member, pointer-to-member -conversions\iref{conv.mem} and qualification -conversions\iref{conv.qual} are performed on both operands to bring them to +If at least one of the operands is a pointer to member, +pointer-to-member conversions\iref{conv.mem}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed on both operands to bring them to their composite pointer type\iref{expr.type}. Comparing pointers to members is defined as follows: @@ -6267,8 +6488,10 @@ pointer type. \item One or both of the second and third operands have pointer-to-member type; -pointer to member conversions\iref{conv.mem} and qualification -conversions\iref{conv.qual} are performed to bring them to their composite +pointer to member conversions\iref{conv.mem}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. \item @@ -6278,6 +6501,60 @@ \end{itemize} +\rSec2[expr.yield]{Yielding a value}% +\indextext{expression!yield}% +\indextext{\idxcode{co_yield}}% + +\begin{bnf} + \nontermdef{yield-expression}\br + \terminal{co_yield} assignment-expression\br + \terminal{co_yield} braced-init-list +\end{bnf} + +\pnum +A \grammarterm{yield-expression} shall appear only within a suspension context +of a function\iref{expr.await}. +Let \placeholder{e} be the operand of the \grammarterm{yield-expression} and +\placeholder{p} be an lvalue naming the promise object of the enclosing +coroutine\iref{dcl.fct.def.coroutine}, then the \grammarterm{yield-expression} +is equivalent to the expression +\tcode{co_await }\placeholder{p}\tcode{.yield_value(}\placeholder{e}\tcode{)}. + +\begin{example} +\begin{codeblock} +template +struct my_generator { + struct promise_type { + T current_value; + @\commentellip@ + auto yield_value(T v) { + current_value = std::move(v); + return std::suspend_always{}; + } + }; + struct iterator { @\commentellip@ }; + iterator begin(); + iterator end(); +}; + +my_generator> g1() { + for (int i = i; i < 10; ++i) co_yield {i,i}; +} +my_generator> g2() { + for (int i = i; i < 10; ++i) co_yield make_pair(i,i); +} + +auto f(int x = co_yield 5); // error: \grammarterm{yield-expression} outside of function suspension context +int a[] = { co_yield 1 }; // error: \grammarterm{yield-expression} outside of function suspension context + +int main() { + auto r1 = g1(); + auto r2 = g2(); + assert(std::equal(r1.begin(), r1.end(), r2.begin(), r2.end())); +} +\end{codeblock} +\end{example} + \rSec2[expr.throw]{Throwing an exception}% \indextext{expression!\idxcode{throw}}% \indextext{exception handling!throwing}% @@ -6285,7 +6562,7 @@ % \begin{bnf} \nontermdef{throw-expression}\br - \terminal{throw} \opt{assignment-expression} + \keyword{throw} \opt{assignment-expression} \end{bnf} \pnum @@ -6372,6 +6649,7 @@ \nontermdef{assignment-expression}\br conditional-expression\br logical-or-expression assignment-operator initializer-clause\br + yield-expression\br throw-expression \end{bnf} @@ -6505,7 +6783,7 @@ requirements as detailed in this subclause; other contexts have different semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements, -assuming that copy elision is performed, +assuming that copy elision\iref{class.copy.elision} is not performed, are called \indexdefn{expression!constant}% \defnx{constant expressions}{constant expression}. \begin{note} Constant expressions can be evaluated @@ -6537,12 +6815,6 @@ its initializing declaration is encountered if it is a constexpr variable, or it is of reference type or of const-qualified integral or enumeration type, and its initializer is a constant initializer. -An object or reference is \defn{usable in constant expressions} -if it is a variable that is usable in constant expressions, -a template parameter object\iref{temp.param}, -a string literal object\iref{lex.string}, -or a non-mutable subobject or reference member -of an object that is usable in constant expressions. \pnum An expression \tcode{e} is a \defnadj{core constant}{expression} @@ -6688,12 +6960,14 @@ a \grammarterm{delete-expression}\iref{expr.delete}; \item -a three-way comparison\iref{expr.spaceship} -comparing pointers that do not point to the same -complete object or to any subobject thereof; +an \grammarterm{await-expression}\iref{expr.await}; + +\item +a \grammarterm{yield-expression}\iref{expr.yield}; \item -a relational\iref{expr.rel} or equality\iref{expr.eq} +a three-way comparison\iref{expr.spaceship}, +relational\iref{expr.rel}, or equality\iref{expr.eq} operator where the result is unspecified; \item @@ -6850,8 +7124,8 @@ An entity is a \defnx{permitted result of a constant expression}{constant expression!permitted result of} if it is an -object with static storage duration that is either not a temporary object or is -a temporary object whose value satisfies the above constraints, or +object with static storage duration that either is not a temporary object or is +a temporary object whose value satisfies the above constraints, or if it is a non-immediate function. \begin{example} \begin{codeblock} diff --git a/source/future.tex b/source/future.tex index a09031cb40..7e801a3c19 100644 --- a/source/future.tex +++ b/source/future.tex @@ -67,13 +67,13 @@ \begin{codeblock} int arr1[5]; int arr2[5]; -bool same = arr1 == arr2; // deprecated, same as \tcode{\&arr[0] == \&arr[1]}, +bool same = arr1 == arr2; // deprecated, same as \tcode{\&arr1[0] == \&arr2[0]}, // does not compare array contents auto cmp = arr1 <=> arr2; // ill-formed \end{codeblock} \end{example} -\rSec1[depr.static_constexpr]{Redeclaration of \tcode{static constexpr} data members} +\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} \pnum For compatibility with prior \Cpp{} International Standards, a \tcode{constexpr} @@ -908,10 +908,9 @@ positions the output sequence \\ \rowsep \tcode{(which \& (ios::in |}\br \tcode{ios::out)) == (ios::in |}\br -\tcode{ios::out))} and\br -\tcode{way ==} either\br -\tcode{ios::beg} or\br -\tcode{ios::end} & +\tcode{ios::out))} and either\br +\tcode{way == ios::beg} or\br +\tcode{way == ios::end} & positions both the input and the output sequences \\ \rowsep Otherwise & the positioning operation fails. \\ @@ -1515,6 +1514,32 @@ \end{codeblock} \end{example} +\rSec1[depr.move.iter.elem]{Deprecated \tcode{move_iterator} access} + +\pnum +The following member is declared in addition to those members +specified in \ref{move.iter.elem}: + +\begin{codeblock} +namespace std { + template + class move_iterator { + public: + constexpr pointer operator->() const; + }; +} +\end{codeblock} + +\indexlibrarymember{operator->}{move_iterator}% +\begin{itemdecl} +constexpr pointer operator->() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{current}. +\end{itemdescr} + \rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access} \pnum diff --git a/source/iostreams.tex b/source/iostreams.tex index ae814c4881..1ec261bd50 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -7794,9 +7794,9 @@ \tcode{ios_base::out)) ==}\br \tcode{(ios_base::in |}\br \tcode{ios_base::out)}\br -and \tcode{way ==} either\br -\tcode{ios_base::beg} or\br -\tcode{ios_base::end} & +and either\br +\tcode{way == ios_base::beg} or\br +\tcode{way == ios_base::end} & positions both the input and the output sequences \\ \rowsep Otherwise & the positioning operation fails. \\ @@ -10822,13 +10822,13 @@ void swap(path& lhs, path& rhs) noexcept; size_t hash_value(const path& p) noexcept; - // \ref{fs.class.filesystem_error}, filesystem errors + // \ref{fs.class.filesystem.error}, filesystem errors class filesystem_error; - // \ref{fs.class.directory_entry}, directory entries + // \ref{fs.class.directory.entry}, directory entries class directory_entry; - // \ref{fs.class.directory_iterator}, directory iterators + // \ref{fs.class.directory.iterator}, directory iterators class directory_iterator; // \ref{fs.dir.itr.nonmembers}, range access for directory iterators @@ -10842,7 +10842,7 @@ recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; - // \ref{fs.class.file_status}, file status + // \ref{fs.class.file.status}, file status class file_status; struct space_info { @@ -12862,7 +12862,7 @@ \effects Equivalent to: \tcode{return path(lhs) /= rhs;} \end{itemdescr} -\rSec2[fs.class.filesystem_error]{Class \tcode{filesystem_error}} +\rSec2[fs.class.filesystem.error]{Class \tcode{filesystem_error}} \indexlibrary{\idxcode{filesystem_error}}% \begin{codeblock} @@ -12886,7 +12886,7 @@ objects thrown as exceptions to report file system errors from functions described in this subclause. -\rSec3[fs.filesystem_error.members]{Members} +\rSec3[fs.filesystem.error.members]{Members} \pnum Constructors are provided that store zero, one, or two paths associated with @@ -12904,7 +12904,7 @@ \item \tcode{code() == ec}, \item \tcode{path1().empty() == true}, \item \tcode{path2().empty() == true}, and -\item \tcode{string_view(what()).find(what_arg)} \tcode{!= string_view::npos}. +\item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos}. \end{itemize} \end{itemdescr} @@ -12920,7 +12920,7 @@ \item \tcode{code() == ec}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, \item \tcode{path2().empty() == true}, and -\item \tcode{string_view(what()).find(what_arg)} \tcode{!= string_view::npos}. +\item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos}. \end{itemize} \end{itemdescr} @@ -12936,7 +12936,7 @@ \item \tcode{code() == ec}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, \item \tcode{path2()} returns a reference to the stored copy of \tcode{p2}, and -\item \tcode{string_view(what()).find(what_arg)} \tcode{!= string_view::npos}. +\item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos}. \end{itemize} \end{itemdescr} @@ -13003,16 +13003,16 @@ \end{note} \\\rowsep \end{floattable} -\rSec3[fs.enum.file_type]{Enum class \tcode{file_type}} +\rSec3[fs.enum.file.type]{Enum class \tcode{file_type}} \indexlibrary{\idxcode{file_type}}% \pnum This enum class specifies constants used to identify file types, -with the meanings listed in \tref{fs.enum.file_type}. +with the meanings listed in \tref{fs.enum.file.type}. The values of the constants are distinct. \begin{floattable} -{Enum class \tcode{file_type}}{tab:fs.enum.file_type} +{Enum class \tcode{file_type}}{tab:fs.enum.file.type} {lp{4.5in}} \topline \lhdr{Constant} & @@ -13217,14 +13217,14 @@ Skip directories that would otherwise result in permission denied. \\ \end{floattable} -\rSec2[fs.class.file_status]{Class \tcode{file_status}} +\rSec2[fs.class.file.status]{Class \tcode{file_status}} \indexlibrary{\idxcode{file_status}}% \begin{codeblock} namespace std::filesystem { class file_status { public: - // \ref{fs.file_status.cons}, constructors and destructor + // \ref{fs.file.status.cons}, constructors and destructor file_status() noexcept : file_status(file_type::none) {} explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; @@ -13236,11 +13236,11 @@ file_status& operator=(const file_status&) noexcept = default; file_status& operator=(file_status&&) noexcept = default; - // \ref{fs.file_status.mods}, modifiers + // \ref{fs.file.status.mods}, modifiers void type(file_type ft) noexcept; void permissions(perms prms) noexcept; - // \ref{fs.file_status.obs}, observers + // \ref{fs.file.status.obs}, observers file_type type() const noexcept; perms permissions() const noexcept; }; @@ -13250,7 +13250,7 @@ \pnum An object of type \tcode{file_status} stores information about the type and permissions of a file. -\rSec3[fs.file_status.cons]{Constructors} +\rSec3[fs.file.status.cons]{Constructors} \indexlibrary{\idxcode{file_status}!constructor}% \begin{itemdecl} @@ -13262,7 +13262,7 @@ \ensures \tcode{type() == ft} and \tcode{permissions() == prms}. \end{itemdescr} -\rSec3[fs.file_status.obs]{Observers} +\rSec3[fs.file.status.obs]{Observers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -13286,7 +13286,7 @@ \tcode{operator=}, or \tcode{permissions(perms)} function. \end{itemdescr} -\rSec3[fs.file_status.mods]{Modifiers} +\rSec3[fs.file.status.mods]{Modifiers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -13308,7 +13308,7 @@ \ensures \tcode{permissions() == prms}. \end{itemdescr} -\rSec2[fs.class.directory_entry]{Class \tcode{directory_entry}} +\rSec2[fs.class.directory.entry]{Class \tcode{directory_entry}} \indexlibrary{\idxcode{directory_entry}}% \begin{codeblock} @@ -13396,7 +13396,7 @@ \pnum \begin{note} For purposes of exposition, -class \tcode{directory_iterator}\iref{fs.class.directory_iterator} +class \tcode{directory_iterator}\iref{fs.class.directory.iterator} is shown above as a friend of class \tcode{directory_entry}. Friendship allows the \tcode{directory_iterator} implementation to cache already available attribute values @@ -13507,7 +13507,7 @@ \pnum \begin{note} -Implementations of \tcode{directory_iterator}\iref{fs.class.directory_iterator} +Implementations of \tcode{directory_iterator}\iref{fs.class.directory.iterator} are prohibited from directly or indirectly calling the \tcode{refresh} function since it must access the external file system, and the objective of caching is to avoid unnecessary file system accesses. @@ -13794,13 +13794,13 @@ \returns \tcode{pathobject >= rhs.pathobject}. \end{itemdescr} -\rSec2[fs.class.directory_iterator]{Class \tcode{directory_iterator}} +\rSec2[fs.class.directory.iterator]{Class \tcode{directory_iterator}} \indexlibrary{\idxcode{directory_iterator}}% \pnum An object of type \tcode{directory_iterator} provides an iterator for a sequence of \tcode{directory_entry} elements representing the -path and any cached attribute values\iref{fs.class.directory_entry} +path and any cached attribute values\iref{fs.class.directory.entry} for each file in a directory or in an \impldef{type of a directory-like file} directory-like file type. \begin{note} For iteration into sub-directories, see class \tcode{recursive_directory_iterator}\iref{fs.class.rec.dir.itr}. @@ -13873,13 +13873,13 @@ \pnum Constructors and non-const \tcode{directory_iterator} member functions -store the values of any cached attributes\iref{fs.class.directory_entry} +store the values of any cached attributes\iref{fs.class.directory.entry} in the \tcode{directory_entry} element returned by \tcode{operator*()}. \tcode{directory_iterator} member functions shall not directly or indirectly call any \tcode{directory_entry} \tcode{refresh} function. \begin{note} The exact mechanism for storing cached attribute values is not exposed to users. -For exposition, class \tcode{directory_iterator} is shown in \ref{fs.class.directory_entry} +For exposition, class \tcode{directory_iterator} is shown in \ref{fs.class.directory.entry} as a friend of class \tcode{directory_entry}. \end{note} @@ -14506,7 +14506,7 @@ \begin{itemize} \item If \tcode{f.type()} or \tcode{t.type()} is an implementation-defined -file type\iref{fs.enum.file_type}, then the effects are +file type\iref{fs.enum.file.type}, then the effects are \impldef{effect of \tcode{filesystem::copy}}. \item @@ -14628,7 +14628,7 @@ \end{itemdescr} -\rSec3[fs.op.copy_file]{Copy file} +\rSec3[fs.op.copy.file]{Copy file} \indexlibrary{\idxcode{copy_file}}% \begin{itemdecl} @@ -14684,7 +14684,7 @@ \item \tcode{exists(to)} is \tcode{false}, or \item \tcode{(options \& copy_options::overwrite_existing) != copy_options::none}, or \item \tcode{(options \& copy_options::update_existing) \: \: != copy_options::none} and \tcode{from} - is more recent than \tcode{to}, determined as if by use of the \tcode{last_write_time} function\iref{fs.op.last_write_time}. + is more recent than \tcode{to}, determined as if by use of the \tcode{last_write_time} function\iref{fs.op.last.write.time}. \end{itemize} \item @@ -14703,7 +14703,7 @@ \complexity At most one direct or indirect invocation of \tcode{status(to)}. \end{itemdescr} -\rSec3[fs.op.copy_symlink]{Copy symlink} +\rSec3[fs.op.copy.symlink]{Copy symlink} \indexlibrary{\idxcode{copy_symlink}}% \begin{itemdecl} @@ -14725,7 +14725,7 @@ \end{itemdescr} -\rSec3[fs.op.create_directories]{Create directories} +\rSec3[fs.op.create.directories]{Create directories} \indexlibrary{\idxcode{create_directories}}% \begin{itemdecl} @@ -14742,8 +14742,6 @@ \returns \tcode{true} if a new directory was created for the directory \tcode{p} resolves to, otherwise \tcode{false}. - The signature with argument \tcode{ec} - returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. @@ -14754,7 +14752,7 @@ \end{itemdescr} -\rSec3[fs.op.create_directory]{Create directory} +\rSec3[fs.op.create.directory]{Create directory} \indexlibrary{\idxcode{create_directory}}% \begin{itemdecl} @@ -14765,13 +14763,13 @@ \begin{itemdescr} \pnum \effects Creates the directory \tcode{p} resolves to, - as if by POSIX \tcode{mkdir()} with a second argument of + as if by POSIX \tcode{mkdir} with a second argument of \tcode{static_cast(perms::all)}. - Creation failure because \tcode{p} already exists is not an error. + If \tcode{mkdir} fails because \tcode{p} resolves to an existing directory, + no error is reported. Otherwise on failure an error is reported. \pnum \returns \tcode{true} if a new directory was created, otherwise \tcode{false}. - The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. @@ -14789,7 +14787,8 @@ directory \tcode{p} resolves to, with attributes copied from directory \tcode{existing_p}. The set of attributes copied is operating system dependent. - Creation failure because \tcode{p} already exists is not an error. + If \tcode{mkdir} fails because \tcode{p} resolves to an existing directory, + no error is reported. Otherwise on failure an error is reported. \begin{note} For POSIX-based operating systems, the attributes are those copied by native API \tcode{stat(existing_p.c_str(), \&attributes_stat)} followed by \tcode{mkdir(p.c_str(), attributes_stat.st_mode)}. For @@ -14798,15 +14797,16 @@ \end{note} \pnum -\returns \tcode{true} if a new directory was created, otherwise \tcode{false}. - The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. +\returns \tcode{true} if a new directory was created + with attributes copied from directory \tcode{existing_p}, + otherwise \tcode{false}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} -\rSec3[fs.op.create_dir_symlk]{Create directory symlink} +\rSec3[fs.op.create.dir.symlk]{Create directory symlink} \indexlibrary{\idxcode{create_directory_symlink}}% \begin{itemdecl} @@ -14838,7 +14838,7 @@ symbolic links regardless of the operating system. \end{note} \end{itemdescr} -\rSec3[fs.op.create_hard_lk]{Create hard link} +\rSec3[fs.op.create.hard.lk]{Create hard link} \indexlibrary{\idxcode{create_hard_link}}% \begin{itemdecl} @@ -14869,7 +14869,7 @@ Some file systems limit the number of links per file. \end{note} \end{itemdescr} -\rSec3[fs.op.create_symlink]{Create symlink} +\rSec3[fs.op.create.symlink]{Create symlink} \indexlibrary{\idxcode{create_symlink}}% \begin{itemdecl} @@ -14896,7 +14896,7 @@ support symbolic links regardless of the operating system. \end{note} \end{itemdescr} -\rSec3[fs.op.current_path]{Current path} +\rSec3[fs.op.current.path]{Current path} \indexlibrary{\idxcode{current_path}}% \begin{itemdecl} @@ -15019,7 +15019,7 @@ \end{itemdescr} -\rSec3[fs.op.file_size]{File size} +\rSec3[fs.op.file.size]{File size} \indexlibrary{\idxcode{file_size}}% \begin{itemdecl} @@ -15050,7 +15050,7 @@ \end{itemdescr} -\rSec3[fs.op.hard_lk_ct]{Hard link count} +\rSec3[fs.op.hard.lk.ct]{Hard link count} \indexlibrary{\idxcode{hard_link_count}}% \begin{itemdecl} @@ -15069,7 +15069,7 @@ \end{itemdescr} -\rSec3[fs.op.is_block_file]{Is block file} +\rSec3[fs.op.is.block.file]{Is block file} \indexlibrary{\idxcode{is_block_file}}% \begin{itemdecl} @@ -15097,7 +15097,7 @@ \end{itemdescr} -\rSec3[fs.op.is_char_file]{Is character file} +\rSec3[fs.op.is.char.file]{Is character file} \indexlibrary{\idxcode{is_character_file}}% \begin{itemdecl} @@ -15127,7 +15127,7 @@ \end{itemdescr} -\rSec3[fs.op.is_directory]{Is directory} +\rSec3[fs.op.is.directory]{Is directory} \indexlibrary{\idxcode{is_directory}}% \begin{itemdecl} @@ -15156,7 +15156,7 @@ \end{itemdescr} -\rSec3[fs.op.is_empty]{Is empty} +\rSec3[fs.op.is.empty]{Is empty} \indexlibrary{\idxcode{is_empty}!function}% \begin{itemdecl} @@ -15197,7 +15197,7 @@ \end{itemdescr} -\rSec3[fs.op.is_fifo]{Is fifo} +\rSec3[fs.op.is.fifo]{Is fifo} \indexlibrary{\idxcode{is_fifo}}% \begin{itemdecl} @@ -15226,7 +15226,7 @@ \end{itemdescr} -\rSec3[fs.op.is_other]{Is other} +\rSec3[fs.op.is.other]{Is other} \indexlibrary{\idxcode{is_other}}% \begin{itemdecl} @@ -15255,7 +15255,7 @@ \end{itemdescr} -\rSec3[fs.op.is_regular_file]{Is regular file} +\rSec3[fs.op.is.regular.file]{Is regular file} \indexlibrary{\idxcode{is_regular_file}}% \begin{itemdecl} @@ -15297,7 +15297,7 @@ \end{itemdescr} -\rSec3[fs.op.is_socket]{Is socket} +\rSec3[fs.op.is.socket]{Is socket} \indexlibrary{\idxcode{is_socket}}% \begin{itemdecl} @@ -15326,7 +15326,7 @@ \end{itemdescr} -\rSec3[fs.op.is_symlink]{Is symlink} +\rSec3[fs.op.is.symlink]{Is symlink} \indexlibrary{\idxcode{is_symlink}}% \begin{itemdecl} @@ -15355,7 +15355,7 @@ \end{itemdescr} -\rSec3[fs.op.last_write_time]{Last write time} +\rSec3[fs.op.last.write.time]{Last write time} \indexlibrary{\idxcode{last_write_time}}% \begin{itemdecl} @@ -15465,7 +15465,7 @@ \throws As specified in~\ref{fs.err.report}. \end{itemdescr} -\rSec3[fs.op.read_symlink]{Read symlink} +\rSec3[fs.op.read.symlink]{Read symlink} \indexlibrary{\idxcode{read_symlink}}% \begin{itemdecl} @@ -15550,7 +15550,7 @@ \end{itemdescr} -\rSec3[fs.op.remove_all]{Remove all} +\rSec3[fs.op.remove.all]{Remove all} \indexlibrary{\idxcode{remove_all}}% \begin{itemdecl} @@ -15612,7 +15612,7 @@ \end{itemdescr} -\rSec3[fs.op.resize_file]{Resize file} +\rSec3[fs.op.resize.file]{Resize file} \indexlibrary{\idxcode{resize_file}}% \begin{itemdecl} @@ -15751,7 +15751,7 @@ \item Otherwise, if the attributes indicate a socket, as if by POSIX \tcode{S_ISSOCK}, returns \tcode{file_status(file_type::socket, prms)}. \item Otherwise, if the attributes indicate an implementation-defined - file type\iref{fs.enum.file_type}, + file type\iref{fs.enum.file.type}, returns \tcode{file_status(file_type::\placeholdernc{A}, prms)}, where \tcode{\placeholdernc{A}} is the constant for the \impldef{file type of the file argument of \tcode{filesystem::status}} file type. @@ -15765,7 +15765,7 @@ \end{itemdescr} -\rSec3[fs.op.status_known]{Status known} +\rSec3[fs.op.status.known]{Status known} \indexlibrary{\idxcode{status_known}}% \begin{itemdecl} @@ -15778,7 +15778,7 @@ \end{itemdescr} -\rSec3[fs.op.symlink_status]{Symlink status} +\rSec3[fs.op.symlink.status]{Symlink status} \indexlibrary{\idxcode{symlink_status}}% \begin{itemdecl} @@ -15813,7 +15813,7 @@ \end{itemdescr} -\rSec3[fs.op.temp_dir_path]{Temporary directory path} +\rSec3[fs.op.temp.dir.path]{Temporary directory path} \indexlibrary{\idxcode{temp_directory_path}}% \begin{itemdecl} @@ -15848,7 +15848,7 @@ \end{example} \end{itemdescr} -\rSec3[fs.op.weakly_canonical]{Weakly canonical} +\rSec3[fs.op.weakly.canonical]{Weakly canonical} \indexlibrary{\idxcode{weakly_canonical}}% \begin{itemdecl} diff --git a/source/iterators.tex b/source/iterators.tex index a2bba557d6..505093f841 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -197,11 +197,11 @@ // \ref{alg.req.mergeable}, concept \tcode{Mergeable} template, class P1 = identity, class P2 = identity> + class R = ranges::less, class P1 = identity, class P2 = identity> concept Mergeable = @\seebelow@; // \ref{alg.req.sortable}, concept \tcode{Sortable} - template, class P = identity> + template concept Sortable = @\seebelow@; // \ref{iterator.primitives}, primitives @@ -438,6 +438,9 @@ template constexpr auto size(const C& c) -> decltype(c.size()); template constexpr size_t size(const T (&array)[N]) noexcept; + template constexpr auto ssize(const C& c) + -> common_type_t>; + template constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; template [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty()); template [[nodiscard]] constexpr bool empty(const T (&array)[N]) noexcept; template [[nodiscard]] constexpr bool empty(initializer_list il) noexcept; @@ -1764,7 +1767,7 @@ \tcode{*r} & unspecified & & - \requires \tcode{r} is dereferenceable. \\ \rowsep + \expects \tcode{r} is dereferenceable. \\ \rowsep \tcode{++r} & \tcode{X\&} & @@ -1830,23 +1833,23 @@ \tcode{a != b} & contextually convertible to \tcode{bool} & \tcode{!(a == b)} & - \requires \orange{a}{b} is in the domain of \tcode{==}. \\ \rowsep + \expects \orange{a}{b} is in the domain of \tcode{==}. \\ \rowsep \tcode{*a} & \tcode{reference}, convertible to \tcode{T} & & - \requires \tcode{a} is dereferenceable.\br + \expects \tcode{a} is dereferenceable.\br The expression\br \tcode{(void)*a, *a} is equivalent to \tcode{*a}.\br If \tcode{a == b} and \orange{a}{b} is in the domain of \tcode{==} then \tcode{*a} is equivalent to \tcode{*b}. \\ \rowsep \tcode{a->m} & & \tcode{(*a).m} & - \requires \tcode{a} is dereferenceable. \\ \rowsep + \expects \tcode{a} is dereferenceable. \\ \rowsep \tcode{++r} & \tcode{X\&} & & - \requires \tcode{r} is dereferenceable.\br + \expects \tcode{r} is dereferenceable.\br \ensures \tcode{r} is dereferenceable or \tcode{r} is past-the-end;\br any copies of the previous value of \tcode{r} are no longer required to be dereferenceable nor to be in the domain of \tcode{==}. \\ \rowsep @@ -1905,14 +1908,14 @@ \tcode{*r = o} & result is not used & & - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br + \remarks After this operation \tcode{r} is not required to be dereferenceable.\br \ensures \tcode{r} is incrementable. \\ \rowsep \tcode{++r} & \tcode{X\&} & & \tcode{addressof(r) == addressof(++r)}.\br - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br + \remarks After this operation \tcode{r} is not required to be dereferenceable.\br \ensures \tcode{r} is incrementable. \\ \rowsep \tcode{r++} & @@ -1920,12 +1923,12 @@ \tcode{\{ X tmp = r;}\br \tcode{ ++r;}\br \tcode{ return tmp; \}} & - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br + \remarks After this operation \tcode{r} is not required to be dereferenceable.\br \ensures \tcode{r} is incrementable. \\ \rowsep \tcode{*r++ = o} & result is not used && - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br + \remarks After this operation \tcode{r} is not required to be dereferenceable.\br \ensures \tcode{r} is incrementable. \\ \end{libreqtab4b} @@ -2048,7 +2051,7 @@ \tcode{\dcr r} & \tcode{X\&} & & - \requires there exists \tcode{s} such that \tcode{r == ++s}.\br + \expects there exists \tcode{s} such that \tcode{r == ++s}.\br \ensures \tcode{r} is dereferenceable.\br \tcode{\dcr(++r) == r}.\br \tcode{\dcr r == \dcr s} implies \tcode{r == s}.\br @@ -2111,7 +2114,7 @@ \tcode{r -= n} & \tcode{X\&} & \tcode{return r += -n;} & - \requires the absolute value of \tcode{n} is in the range of + \expects the absolute value of \tcode{n} is in the range of representable values of \tcode{difference_type}. \\ \rowsep \tcode{a - n} & @@ -2122,7 +2125,7 @@ \tcode{b - a} & \tcode{difference_type} & \tcode{return n} & - \requires there exists a value \tcode{n} of type \tcode{difference_type} such that \tcode{a + n == b}.\br + \expects there exists a value \tcode{n} of type \tcode{difference_type} such that \tcode{a + n == b}.\br \tcode{b == a + (b - a)}. \\ \rowsep \tcode{a[n]} & @@ -2274,7 +2277,7 @@ \pnum \begin{note} -The \tcode{ranges::less<>} function object type +The \tcode{ranges::less} function object type used in the concepts below imposes constraints on the concepts' arguments in addition to those that appear in the concepts' bodies\iref{range.cmp}. \end{note} @@ -2425,7 +2428,7 @@ \indexlibrary{\idxcode{Mergeable}}% \begin{codeblock} -template, +template concept Mergeable = InputIterator && @@ -2444,7 +2447,7 @@ \indexlibrary{\idxcode{Sortable}}% \begin{codeblock} -template, class P = identity> +template concept Sortable = Permutable && IndirectStrictWeakOrder>; @@ -3269,7 +3272,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() == y.base()} shall be valid and +\tcode{x.base() == y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3288,7 +3291,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() != y.base()} shall be valid and +\tcode{x.base() != y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3307,7 +3310,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() > y.base()} shall be valid and +\tcode{x.base() > y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3326,7 +3329,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() < y.base()} shall be valid and +\tcode{x.base() < y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3345,7 +3348,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() >= y.base()} shall be valid and +\tcode{x.base() >= y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3364,7 +3367,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() <= y.base()} shall be valid and +\tcode{x.base() <= y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -3906,7 +3909,6 @@ constexpr iterator_type base() const; constexpr reference operator*() const; - constexpr pointer operator->() const; constexpr move_iterator& operator++(); constexpr auto operator++(int); @@ -4014,12 +4016,11 @@ \begin{itemdescr} \pnum -\effects Constructs a \tcode{move_iterator}, initializing -\tcode{current} with \tcode{u.base()}. +\mandates \tcode{U} is convertible to \tcode{Iterator}. \pnum -\requires \tcode{U} shall be convertible to -\tcode{Iterator}. +\effects Constructs a \tcode{move_iterator}, initializing +\tcode{current} with \tcode{u.base()}. \end{itemdescr} \indexlibrarymember{operator=}{move_iterator}% @@ -4029,12 +4030,11 @@ \begin{itemdescr} \pnum -\effects Assigns \tcode{u.base()} to -\tcode{current}. +\mandates \tcode{U} is convertible to \tcode{Iterator}. \pnum -\requires \tcode{U} shall be convertible to -\tcode{Iterator}. +\effects Assigns \tcode{u.base()} to +\tcode{current}. \end{itemdescr} \rSec3[move.iter.op.conv]{Conversion} @@ -4061,16 +4061,6 @@ \effects Equivalent to: \tcode{return ranges::iter_move(current);} \end{itemdescr} -\indexlibrarymember{operator->}{move_iterator}% -\begin{itemdecl} -constexpr pointer operator->() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{current}. -\end{itemdescr} - \indexlibrarymember{operator[]}{move_iterator}% \begin{itemdecl} constexpr reference operator[](difference_type n) const; @@ -4206,7 +4196,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() == y.base()} shall be valid and +\tcode{x.base() == y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4229,7 +4219,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() == y.base()} shall be valid and +\tcode{x.base() == y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4245,7 +4235,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() < y.base()} shall be valid and +\tcode{x.base() < y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4261,7 +4251,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{y.base() < x.base()} shall be valid and +\tcode{y.base() < x.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4277,7 +4267,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{y.base() < x.base()} shall be valid and +\tcode{y.base() < x.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4293,7 +4283,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x.base() < y.base()} shall be valid and +\tcode{x.base() < y.base()} is well-formed and convertible to \tcode{bool}. \pnum @@ -4331,7 +4321,7 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{x + n} shall be valid and have type \tcode{Iterator}. +\tcode{x + n} is well-formed and has type \tcode{Iterator}. \pnum \returns \tcode{x + n}. @@ -5569,51 +5559,9 @@ \pnum \indexlibrary{\idxcode{istream_iterator}}% -The class template -\tcode{istream_iterator} -is an input iterator\iref{input.iterators} that -reads (using -\tcode{operator>>}) -successive elements from the input stream for which it was constructed. -After it is constructed, and every time -\tcode{++} -is used, the iterator reads and stores a value of -\tcode{T}. -If the iterator fails to read and store a value of \tcode{T} -(\tcode{fail()} -on the stream returns -\tcode{true}), -the iterator becomes equal to the -\term{end-of-stream} -iterator value. -The constructor with no arguments -\tcode{istream_iterator()} -always constructs -an end-of-stream input iterator object, which is the only legitimate iterator to be used -for the end condition. -The result of -\tcode{operator*} -on an end-of-stream iterator is not defined. -For any other iterator value a -\tcode{const T\&} -is returned. -The result of -\tcode{operator->} -on an end-of-stream iterator is not defined. -For any other iterator value a -\tcode{const T*} -is returned. -The behavior of a program that applies \tcode{operator++()} to an end-of-stream -iterator is undefined. -It is impossible to store things into istream iterators. -The type \tcode{T} shall satisfy the \oldconcept{DefaultConstructible}, -\oldconcept{CopyConstructible}, and \oldconcept{CopyAssignable} requirements. - -\pnum -Two end-of-stream iterators are always equal. -An end-of-stream iterator is not -equal to a non-end-of-stream iterator. -Two non-end-of-stream iterators are equal when they are constructed from the same stream. +The class template \tcode{istream_iterator} +is an input iterator\iref{input.iterators} that reads successive elements +from the input stream for which it was constructed. \begin{codeblock} namespace std { @@ -5654,6 +5602,10 @@ } \end{codeblock} +\pnum +The type \tcode{T} shall meet the \oldconcept{DefaultConstructible}, +\oldconcept{CopyConstructible}, and \oldconcept{CopyAssignable} requirements. + \rSec3[istream.iterator.cons]{Constructors and destructor} \indexlibrary{\idxcode{istream_iterator}!constructor}% @@ -5665,12 +5617,16 @@ \begin{itemdescr} \pnum \effects -Constructs the end-of-stream iterator. -If \tcode{is_trivially_default_constructible_v} is \tcode{true}, -then these constructors are constexpr constructors. +Constructs the end-of-stream iterator, value-initializing \tcode{value}. \pnum -\ensures \tcode{in_stream == nullptr}. +\ensures \tcode{in_stream == nullptr} is \tcode{true}. + +\pnum +\remarks +If the initializer \tcode{T()} in the declaration \tcode{auto x = T();} +is a constant initializer\iref{expr.const}, +then these constructors are \tcode{constexpr} constructors. \end{itemdescr} @@ -5682,12 +5638,9 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{in_stream} with \tcode{addressof(s)}. -\tcode{value} may be initialized during -construction or the first time it is referenced. - -\pnum -\ensures \tcode{in_stream == addressof(s)}. +Initializes \tcode{in_stream} with \tcode{addressof(s)}, +value-initializes \tcode{value}, +and then calls \tcode{operator++()}. \end{itemdescr} @@ -5698,13 +5651,12 @@ \begin{itemdescr} \pnum -\effects -Constructs a copy of \tcode{x}. -If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, -then this constructor is a trivial copy constructor. +\ensures \tcode{in_stream == x.in_stream} is \tcode{true}. \pnum -\ensures \tcode{in_stream == x.in_stream}. +\remarks +If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, +then this constructor is trivial. \end{itemdescr} \indexlibrary{\idxcode{istream_iterator}!destructor}% @@ -5714,8 +5666,7 @@ \begin{itemdescr} \pnum -\effects -The iterator is destroyed. +\remarks If \tcode{is_trivially_destructible_v} is \tcode{true}, then this destructor is trivial. \end{itemdescr} @@ -5728,6 +5679,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{in_stream != nullptr} is \tcode{true}. + \pnum \returns \tcode{value}. @@ -5739,9 +5694,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{in_stream != nullptr} is \tcode{true}. + \pnum \returns -\tcode{addressof(operator*())}. +\tcode{addressof(value)}. \end{itemdescr} \indexlibrarymember{operator++}{istream_iterator}% @@ -5751,11 +5710,15 @@ \begin{itemdescr} \pnum -\requires \tcode{in_stream != nullptr}. +\expects +\tcode{in_stream != nullptr} is \tcode{true}. \pnum -\effects -As if by: \tcode{*in_stream >> value;} +\effects Equivalent to: +\begin{codeblock} +if (!(*in_stream >> value)) + in_stream = nullptr; +\end{codeblock} \pnum \returns @@ -5769,14 +5732,13 @@ \begin{itemdescr} \pnum -\requires \tcode{in_stream != nullptr}. +\expects \tcode{in_stream != nullptr} is \tcode{true}. \pnum -\effects -As if by: +\effects Equivalent to: \begin{codeblock} istream_iterator tmp = *this; -*in_stream >> value; +++*this; return tmp; \end{codeblock} \end{itemdescr} @@ -5897,29 +5859,6 @@ \tcode{delim} with \tcode{delimiter}. \end{itemdescr} - -\indexlibrary{\idxcode{ostream_iterator}!constructor}% -\begin{itemdecl} -ostream_iterator(const ostream_iterator& x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs a copy of \tcode{x}. -\end{itemdescr} - -\indexlibrary{\idxcode{ostream_iterator}!destructor}% -\begin{itemdecl} -~ostream_iterator(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The iterator is destroyed. -\end{itemdescr} - \rSec3[ostream.iterator.ops]{Operations} \indexlibrarymember{operator=}{ostream_iterator}% @@ -6275,9 +6214,9 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{s.rdbuf()} -shall not be a null pointer. +is not a null pointer. \pnum \effects @@ -6292,9 +6231,9 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{s} -shall not be a null pointer. +is not a null pointer. \pnum \effects @@ -6520,6 +6459,26 @@ \pnum \returns \tcode{N}. \end{itemdescr} +\indexlibrary{\idxcode{ssize(C\& c)}}% +\begin{itemdecl} +template constexpr auto ssize(const C& c) + -> common_type_t>; +\end{itemdecl} +\begin{itemdescr} +\pnum \returns +\begin{codeblock} +static_cast>>(c.size()) +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{ssize(T (\&array)[N])}}% +\begin{itemdecl} +template constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum \returns \tcode{N}. +\end{itemdescr} + \indexlibrary{\idxcode{empty(C\& c)}}% \begin{itemdecl} template [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty()); diff --git a/source/lex.tex b/source/lex.tex index 4e76e7152a..1bc1a163dc 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -42,8 +42,9 @@ \begin{note} Previously translated translation units and instantiation units can be preserved individually or in libraries. The separate translation units of a program communicate\iref{basic.link} by (for -example) calls to functions whose identifiers have external linkage, -manipulation of objects whose identifiers have external linkage, or +example) +calls to functions whose identifiers have external or module linkage, +manipulation of objects whose identifiers have external or module linkage, or manipulation of data files. Translation units can be separately translated and then later linked to produce an executable program\iref{basic.link}. \end{note}% @@ -139,7 +140,18 @@ semantically analyzed and translated as a translation unit. \begin{note} The process of analyzing and translating the tokens may occasionally result in one token being replaced by a sequence of other -tokens\iref{temp.names}.\end{note} \begin{note} Source files, translation +tokens\iref{temp.names}.\end{note} +It is +\impldef{whether the sources for +module units and header units +on which the current translation unit has an interface +dependency are required to be available during translation} +whether the sources for +module units and header units +on which the current translation unit has an interface +dependency (\ref{module.unit}, \ref{module.import}) +are required to be available. +\begin{note} Source files, translation units and translated translation units need not necessarily be stored as files, nor need there be any one-to-one correspondence between these entities and any external representation. The description is conceptual @@ -208,21 +220,31 @@ \end{bnf} The character designated by the \grammarterm{universal-character-name} \tcode{\textbackslash -UNNNNNNNN} is that character whose character short name in ISO/IEC 10646 is -\tcode{NNNNNNNN}; the character designated by the \grammarterm{universal-character-name} -\tcode{\textbackslash uNNNN} is that character whose character short name in -ISO/IEC 10646 is \tcode{0000NNNN}. If the hexadecimal value for a -\grammarterm{universal-character-name} corresponds to a surrogate code point (in the -range 0xD800--0xDFFF, inclusive), the program is ill-formed. Additionally, if -the hexadecimal value for a \grammarterm{universal-character-name} outside +U00NNNNNN} is that character +that has \tcode{U+NNNNNN} as a code point short identifier; +the character designated by the \grammarterm{universal-character-name} +\tcode{\textbackslash uNNNN} is that character +that has \tcode{U+NNNN} as a code point short identifier. +If a \grammarterm{universal-character-name} does not correspond to +a code point in ISO/IEC 10646 or +if a \grammarterm{universal-character-name} corresponds to +a surrogate code point, +the program is ill-formed. Additionally, if +a \grammarterm{universal-character-name} outside the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or \grammarterm{r-char-sequence} of a character or -string literal corresponds to a control character (in either of the -ranges 0x00--0x1F or 0x7F--0x9F, both inclusive) or to a character in the basic +string literal corresponds to a control character or +to a character in the basic source character set, the program is ill-formed.\footnote{A sequence of characters resembling a \grammarterm{universal-character-name} in an \grammarterm{r-char-sequence}\iref{lex.string} does not form a \grammarterm{universal-character-name}.} +\begin{note} +ISO/IEC 10646 code points are within the range 0x0-0x10FFFF (inclusive). +A surrogate code point is a value in the range 0xD800-0xDFFF (inclusive). +A control character is a character whose code point is +in either of the ranges 0x0-0x1F or 0x7F-0x9F (both inclusive). +\end{note} \pnum The \defnx{basic execution character set}{character set!basic execution} and the @@ -314,7 +336,20 @@ characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail, except that a \grammarterm{header-name}\iref{lex.header} is only formed -within a \tcode{\#include} directive\iref{cpp.include}. +\begin{itemize} +\item +within a \tcode{\#include} directive\iref{cpp.include}, + +\item +within a \grammarterm{has-include-expression}, or + +\item +outside of any preprocessing directive, +if applying phase 4 of translation to the sequence +of preprocessing tokens produced thus far +is valid and +results in an \grammarterm{import-seq}\iref{cpp.module}. +\end{itemize} \end{itemize} \begin{example} @@ -621,6 +656,12 @@ \end{floattable} \pnum +\indextext{\idxcode{audit}}% +\indextext{\idxcode{axiom}}% +\indextext{\idxcode{import}}% +\indextext{\idxcode{final}}% +\indextext{\idxcode{module}}% +\indextext{\idxcode{override}}% The identifiers in \tref{identifiers.special} have a special meaning when appearing in a certain context. When referred to in the grammar, these identifiers are used explicitly rather than using the \grammarterm{identifier} grammar production. @@ -628,14 +669,17 @@ \grammarterm{identifier} has a special meaning is resolved to interpret the token as a regular \grammarterm{identifier}. -\begin{floattable}{Identifiers with special meaning}{tab:identifiers.special} -{llll} -\topline -\tcode{audit} & -\tcode{axiom} & -\tcode{final} & -\tcode{override} \\ -\end{floattable} +\begin{multicolfloattable}{Identifiers with special meaning}{tab:identifiers.special} +{lll} +\keyword{audit} \\ +\keyword{axiom} \\ +\columnbreak +\keyword{final} \\ +\keyword{import} \\ +\columnbreak +\keyword{module} \\ +\keyword{override} \\ +\end{multicolfloattable} \pnum \indextext{\idxcode{_}|see{character, underscore}}% @@ -672,91 +716,94 @@ \begin{multicolfloattable}{Keywords}{tab:keywords} {lllll} -\tcode{alignas} \\ -\tcode{alignof} \\ -\tcode{asm} \\ -\tcode{auto} \\ -\tcode{bool} \\ -\tcode{break} \\ -\tcode{case} \\ -\tcode{catch} \\ -\tcode{char} \\ -\tcode{char8_t} \\ -\tcode{char16_t} \\ -\tcode{char32_t} \\ -\tcode{class} \\ -\tcode{concept} \\ -\tcode{const} \\ -\tcode{consteval} \\ +\keyword{alignas} \\ +\keyword{alignof} \\ +\keyword{asm} \\ +\keyword{auto} \\ +\keyword{bool} \\ +\keyword{break} \\ +\keyword{case} \\ +\keyword{catch} \\ +\keyword{char} \\ +\keyword{char8_t} \\ +\keyword{char16_t} \\ +\keyword{char32_t} \\ +\keyword{class} \\ +\keyword{concept} \\ +\keyword{const} \\ +\keyword{consteval} \\ \columnbreak -\tcode{constexpr} \\ -\tcode{const_cast} \\ -\tcode{continue} \\ -\tcode{decltype} \\ -\tcode{default} \\ -\tcode{delete} \\ -\tcode{do} \\ -\tcode{double} \\ -\tcode{dynamic_cast} \\ -\tcode{else} \\ -\tcode{enum} \\ -\tcode{explicit} \\ -\tcode{export} \\ -\tcode{extern} \\ -\tcode{false} \\ -\tcode{float} \\ +\keyword{constexpr} \\ +\keyword{const_cast} \\ +\keyword{continue} \\ +\keyword{co_await} \\ +\keyword{co_return} \\ +\keyword{co_yield} \\ +\keyword{decltype} \\ +\keyword{default} \\ +\keyword{delete} \\ +\keyword{do} \\ +\keyword{double} \\ +\keyword{dynamic_cast} \\ +\keyword{else} \\ +\keyword{enum} \\ +\keyword{explicit} \\ +\keyword{export} \\ \columnbreak -\tcode{for} \\ -\tcode{friend} \\ -\tcode{goto} \\ -\tcode{if} \\ -\tcode{inline} \\ -\tcode{int} \\ -\tcode{long} \\ -\tcode{mutable} \\ -\tcode{namespace} \\ -\tcode{new} \\ -\tcode{noexcept} \\ -\tcode{nullptr} \\ -\tcode{operator} \\ -\tcode{private} \\ -\tcode{protected} \\ -\tcode{public} \\ +\keyword{extern} \\ +\keyword{false} \\ +\keyword{float} \\ +\keyword{for} \\ +\keyword{friend} \\ +\keyword{goto} \\ +\keyword{if} \\ +\keyword{inline} \\ +\keyword{int} \\ +\keyword{long} \\ +\keyword{mutable} \\ +\keyword{namespace} \\ +\keyword{new} \\ +\keyword{noexcept} \\ +\keyword{nullptr} \\ +\keyword{operator} \\ \columnbreak -\tcode{register} \\ -\tcode{reinterpret_cast} \\ -\tcode{requires} \\ -\tcode{return} \\ -\tcode{short} \\ -\tcode{signed} \\ -\tcode{sizeof} \\ -\tcode{static} \\ -\tcode{static_assert} \\ -\tcode{static_cast} \\ -\tcode{struct} \\ -\tcode{switch} \\ -\tcode{template} \\ -\tcode{this} \\ -\tcode{thread_local} \\ -\tcode{throw} \\ +\keyword{private} \\ +\keyword{protected} \\ +\keyword{public} \\ +\keyword{register} \\ +\keyword{reinterpret_cast} \\ +\keyword{requires} \\ +\keyword{return} \\ +\keyword{short} \\ +\keyword{signed} \\ +\keyword{sizeof} \\ +\keyword{static} \\ +\keyword{static_assert} \\ +\keyword{static_cast} \\ +\keyword{struct} \\ +\keyword{switch} \\ +\keyword{template} \\ \columnbreak -\tcode{true} \\ -\tcode{try} \\ -\tcode{typedef} \\ -\tcode{typeid} \\ -\tcode{typename} \\ -\tcode{union} \\ -\tcode{unsigned} \\ -\tcode{using} \\ -\tcode{virtual} \\ -\tcode{void} \\ -\tcode{volatile} \\ -\tcode{wchar_t} \\ -\tcode{while} \\ +\keyword{this} \\ +\keyword{thread_local} \\ +\keyword{throw} \\ +\keyword{true} \\ +\keyword{try} \\ +\keyword{typedef} \\ +\keyword{typeid} \\ +\keyword{typename} \\ +\keyword{union} \\ +\keyword{unsigned} \\ +\keyword{using} \\ +\keyword{virtual} \\ +\keyword{void} \\ +\keyword{volatile} \\ +\keyword{wchar_t} \\ +\keyword{while} \\ \end{multicolfloattable} -\begin{note} The \tcode{export} and \tcode{register} keywords are unused but -are reserved for future use.\end{note} +\begin{note} The \keyword{register} keyword is unused but +is reserved for future use.\end{note} \pnum Furthermore, the alternative representations shown in @@ -768,8 +815,8 @@ \begin{floattable}{Alternative representations}{tab:alternative.representations} {llllll} \topline -\tcode{and} & \tcode{and_eq} & \tcode{bitand} & \tcode{bitor} & \tcode{compl} & \tcode{not} \\ -\tcode{not_eq} & \tcode{or} & \tcode{or_eq} & \tcode{xor} & \tcode{xor_eq} & \\ +\keyword{and} & \keyword{and_eq} & \keyword{bitand} & \keyword{bitor} & \keyword{compl} & \keyword{not} \\ +\keyword{not_eq} & \keyword{or} & \keyword{or_eq} & \keyword{xor} & \keyword{xor_eq} & \\ \end{floattable}% \indextext{keyword|)}% @@ -1132,37 +1179,46 @@ The value of a UTF-8 character literal is equal to its ISO/IEC 10646 code point value, provided that the code point value -is representable with a single UTF-8 code unit -(that is, provided it is in the C0 Controls and Basic Latin Unicode block). +can be encoded as a single UTF-8 code unit. +\begin{note} +That is, provided the code point value is in the range 0x0-0x7F (inclusive). +\end{note} If the value is not representable with a single UTF-8 code unit, the program is ill-formed. A UTF-8 character literal containing multiple \grammarterm{c-char}{s} is ill-formed. \pnum -\indextext{literal!character!\tcode{char16_t}}% -\indextext{char16_t character@\tcode{char16_t} character}% +\indextext{literal!character!UTF-16}% \indextext{type!\idxcode{char16_t}}% A character literal that begins with the letter \tcode{u}, such as \tcode{u'x'}, \indextext{prefix!\idxcode{u}}% -is a character literal of type \tcode{char16_t}. The value -of a \tcode{char16_t} character literal containing a single \grammarterm{c-char} is -equal to its ISO/IEC 10646 code point value, provided that the code point value is -representable with a single 16-bit code unit (that is, provided it is in the -basic multi-lingual plane). If the value is not representable -with a single 16-bit code unit, the program is ill-formed. A \tcode{char16_t} character literal +is a character literal of type \tcode{char16_t}, +known as a \defn{UTF-16 character literal}. +The value of a UTF-16 character literal +is equal to its ISO/IEC 10646 code point value, +provided that the code point value is +representable with a single 16-bit code unit. +\begin{note} +That is, provided the code point value is in the range 0x0-0xFFFF (inclusive). +\end{note} +If the value is not representable +with a single 16-bit code unit, the program is ill-formed. +A UTF-16 character literal containing multiple \grammarterm{c-char}{s} is ill-formed. \pnum -\indextext{literal!character!\tcode{char32_t}}% -\indextext{char32_t character@\tcode{char32_t} character}% +\indextext{literal!character!UTF-32}% \indextext{type!\idxcode{char32_t}}% A character literal that begins with the letter \tcode{U}, such as \tcode{U'y'}, \indextext{prefix!\idxcode{U}}% -is a character literal of type \tcode{char32_t}. The value of a -\tcode{char32_t} character literal containing a single \grammarterm{c-char} is equal -to its ISO/IEC 10646 code point value. A \tcode{char32_t} character literal containing +is a character literal of type \tcode{char32_t}, +known as a \defn{UTF-32 character literal}. +The value of a +UTF-32 character literal containing a single \grammarterm{c-char} is equal +to its ISO/IEC 10646 code point value. +A UTF-32 character literal containing multiple \grammarterm{c-char}{s} is ill-formed. \pnum @@ -1530,9 +1586,8 @@ \indextext{literal!string!UTF-8}% A \grammarterm{string-literal} that begins with \tcode{u8}, \indextext{prefix!\idxcode{u8}}% -such as \tcode{u8"asdf"}, is a \defn{UTF-8 string literal}, -also referred to as a \tcode{char8_t} string literal. -A \tcode{char8_t} string literal +such as \tcode{u8"asdf"}, is a \defn{UTF-8 string literal}. +A UTF-8 string literal has type ``array of \placeholder{n} \tcode{const char8_t}'', where \placeholder{n} is the size of the string as defined below; each successive element of the object representation\iref{basic.types} has @@ -1543,28 +1598,39 @@ also referred to as narrow string literals. \pnum -\indextext{literal!string!\idxcode{char16_t}}% +\indextext{literal!string!UTF-16}% \indextext{type!\idxcode{char16_t}}% A \grammarterm{string-literal} that begins with \tcode{u}, \indextext{prefix!\idxcode{u}}% such as \tcode{u"asdf"}, is -a \tcode{char16_t} string literal. A \tcode{char16_t} string literal has +a \defn{UTF-16 string literal}. +A UTF-16 string literal has type ``array of \placeholder{n} \tcode{const char16_t}'', where \placeholder{n} is the -size of the string as defined below; it -is initialized with the given characters. A single \grammarterm{c-char} may +size of the string as defined below; +each successive element of the array +has the value of the corresponding code unit of +the UTF-16 encoding of the string. +\begin{note} +A single \grammarterm{c-char} may produce more than one \tcode{char16_t} character in the form of surrogate pairs. +A surrogate pair is a representation for a single code point +as a sequence of two 16-bit code units. +\end{note} \pnum -\indextext{literal!string!\idxcode{char32_t}}% +\indextext{literal!string!UTF-32}% \indextext{type!\idxcode{char32_t}}% A \grammarterm{string-literal} that begins with \tcode{U}, \indextext{prefix!\idxcode{U}}% such as \tcode{U"asdf"}, is -a \tcode{char32_t} string literal. A \tcode{char32_t} string literal has +a \defn{UTF-32 string literal}. +A UTF-32 string literal has type ``array of \placeholder{n} \tcode{const char32_t}'', where \placeholder{n} is the -size of the string as defined below; it -is initialized with the given characters. +size of the string as defined below; +each successive element of the array +has the value of the corresponding code unit of +the UTF-32 encoding of the string. \pnum \indextext{literal!string!wide}% @@ -1643,14 +1709,14 @@ \tcode{\textbackslash'}, and the double quote \tcode{"} shall be preceded by a \tcode{\textbackslash}, and except that a \grammarterm{universal-character-name} in a -\tcode{char16_t} string literal may yield a surrogate pair. +UTF-16 string literal may yield a surrogate pair. \indextext{string!\idxcode{sizeof}}% In a narrow string literal, a \grammarterm{universal-character-name} may map to more than one \tcode{char} or \tcode{char8_t} element due to \defnadj{multibyte}{encoding}. The size of a \tcode{char32_t} or wide string literal is the total number of escape sequences, \grammarterm{universal-character-name}{s}, and other characters, plus one for the terminating \tcode{U'\textbackslash 0'} or -\tcode{L'\textbackslash 0'}. The size of a \tcode{char16_t} string +\tcode{L'\textbackslash 0'}. The size of a UTF-16 string literal is the total number of escape sequences, \grammarterm{universal-character-name}{s}, and other characters, plus one for each character requiring a surrogate pair, plus one for the terminating diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 73eb33690a..02141c4041 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -319,9 +319,10 @@ \definition{program-defined type}{defns.prog.def.type} \indexdefn{type!program-defined}% -class type or enumeration type +non-closure class type or enumeration type that is not part of the C++ standard library and not defined by the implementation, +or a closure type of a non-implementation-provided lambda expression, or an instantiation of a program-defined specialization \begin{defnote} @@ -337,7 +338,7 @@ \begin{example} \begin{codeblock} std::pair pairs[] = {{2, "foo"}, {1, "bar"}, {0, "baz"}}; -std::ranges::sort(pairs, std::ranges::less<>{}, [](auto const& p) { return p.first; }); +std::ranges::sort(pairs, std::ranges::less{}, [](auto const& p) { return p.first; }); \end{codeblock} sorts the pairs in increasing order of their \tcode{first} members: \begin{codeblock} @@ -1477,7 +1478,9 @@ Two kinds of implementations are defined: \defnx{hosted}{implementation!hosted} and -\defnx{freestanding}{implementation!freestanding}\iref{intro.compliance}. +\defnx{freestanding}{implementation!freestanding}\iref{intro.compliance}; +the kind of the implementation is +\impldef{whether the implementation is hosted or freestanding}. For a hosted implementation, this document describes the set of available headers. @@ -1495,6 +1498,7 @@ \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep +\ref{support.coroutine} & Coroutines support & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ \rowsep \ref{concepts} & Concepts library & \tcode{} \\ \rowsep \ref{meta} & Type traits & \tcode{} \\ \rowsep diff --git a/source/locales.tex b/source/locales.tex index da9cff27cd..542130dfc6 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -4231,8 +4231,8 @@ or in the range from \tcode{'0'} through -\tcode{'9'}, -inclusive) +\tcode{'9'} +(inclusive)) stored in \tcode{digits}. \begin{example} @@ -4664,8 +4664,8 @@ in the range \tcode{'0'} through -\tcode{'9'}, -inclusive, and +\tcode{'9'} +(inclusive) and \tcode{ct} is a reference of type \tcode{const ctype\&} diff --git a/source/macros.tex b/source/macros.tex index f50fbb775b..a17d45b4ea 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -184,10 +184,12 @@ \newcommand{\term}[1]{\textit{#1}} \newcommand{\gterm}[1]{\GrammarStylex{#1}} \newcommand{\fakegrammarterm}[1]{\gterm{#1}} +\newcommand{\keyword}[1]{\tcode{#1}\indextext{\idxcode{#1}}} \newcommand{\grammarterm}[1]{\indexgram{\idxgram{#1}}\gterm{#1}} \newcommand{\grammartermnc}[1]{\indexgram{\idxgram{#1}}\gterm{#1\nocorr}} \newcommand{\placeholder}[1]{\textit{#1}} \newcommand{\placeholdernc}[1]{\textit{#1\nocorr}} +\newcommand{\exposid}[1]{\tcode{\placeholder{#1}}} \newcommand{\defnxname}[1]{\indextext{\idxxname{#1}}\xname{#1}} \newcommand{\defnlibxname}[1]{\indexlibrary{\idxxname{#1}}\xname{#1}} @@ -366,7 +368,6 @@ \newcommand{\howwide}{\diffdef{How widely used}} %% Miscellaneous -\newcommand{\uniquens}{\placeholdernc{unique}} \newcommand{\stage}[1]{\item[Stage #1:]} \newcommand{\doccite}[1]{\textit{#1}} \newcommand{\cvqual}[1]{\textit{#1}} @@ -407,6 +408,26 @@ \lstnewenvironment{codeblock}{\CodeBlockSetup}{} +% Left-align listings titles +\makeatletter +\def\lst@maketitle{\@makeleftcaption\lst@title@dropdelim} +\long\def\@makeleftcaption#1#2{% + \vskip\abovecaptionskip + \sbox\@tempboxa{#1: #2}% + \ifdim \wd\@tempboxa >\hsize + #1: #2\par + \else + \global \@minipagefalse + \hb@xt@\hsize{%\hfil -- REMOVED + \box\@tempboxa\hfil}% + \fi + \vskip\belowcaptionskip}% +\makeatother + +\lstnewenvironment{codeblocktu}[1]{% +\lstset{title={%\parabullnum{Bullets1}{0pt} +#1:}}\CodeBlockSetup}{} + % An environment for command / program output that is not C++ code. \lstnewenvironment{outputblock}{\lstset{language=}}{} @@ -468,6 +489,8 @@ { \newcommand{\nontermdef}[1]{{\BnfNontermshape##1\itcorr}\indexgrammar{\idxgram{##1}}\textnormal{:}} \newcommand{\terminal}[1]{{\BnfTermshape ##1}} + \renewcommand{\keyword}[1]{\terminal{##1}\indextext{\idxcode{##1}}} + \renewcommand{\exposid}[1]{\terminal{\placeholder{##1}}} \newcommand{\descr}[1]{\textnormal{##1}} \newcommand{\bnfindent}{\hspace*{\bnfindentfirst}} \newcommand{\bnfindentfirst}{\BnfIndent} diff --git a/source/modules.tex b/source/modules.tex new file mode 100644 index 0000000000..b5b476e404 --- /dev/null +++ b/source/modules.tex @@ -0,0 +1,982 @@ +%!TEX root = std.tex +\rSec0[module]{Modules}% + +\gramSec[gram.module]{Modules} + +\rSec1[module.unit]{Module units and purviews} + +\begin{bnf} +\nontermdef{module-declaration}\br + \opt{\keyword{export}} \keyword{module} module-name \opt{module-partition} \opt{attribute-specifier-seq} \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{module-name}\br + \opt{module-name-qualifier} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{module-partition}\br + \terminal{:} \opt{module-name-qualifier} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{module-name-qualifier}\br + identifier \terminal{.}\br + module-name-qualifier identifier \terminal{.} +\end{bnf} + +\pnum +A \defn{module unit} is a translation unit that contains +a \grammarterm{module-declaration}. +A \defnadj{named}{module} is the +collection of module units with the same \grammarterm{module-name}. +The identifiers \tcode{module} and \tcode{import} +shall not appear as \grammarterm{identifier}{s} +in a \grammarterm{module-name} or \grammarterm{module-partition}. +The optional \grammarterm{attribute-specifier-seq} +appertains to the \grammarterm{module-declaration}. + +\pnum +A \defn{module interface unit} is a module unit whose +\grammarterm{module-declaration} contains the \tcode{export} keyword; +any other module unit is a \defn{module implementation unit}. +A named module shall contain exactly one module interface unit +with no \grammarterm{module-partition}, known as the +\defn{primary module interface unit} of the module; +no diagnostic is required. + +\pnum +A \defn{module partition} is +a module unit whose \grammarterm{module-declaration} contains +a \grammarterm{module-partition}. +A named module shall not contain multiple module partitions with +the same \grammarterm{module-partition}. +All module partitions of a module +that are module interface units +shall be directly or indirectly exported +by the primary module interface unit\iref{module.import}. +No diagnostic is required for a violation of these rules. +\begin{note} +Module partitions can be imported only by +other module units in the same module. +The division of a module into module units +is not visible outside the module. +\end{note} + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module A; +export import :Foo; +export int baz(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module A:Foo; +import :Internals; +export int foo() { return 2 * (bar() + 1); } +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +module A:Internals; +int bar(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#4} +module A; +import :Internals; +int bar() { return baz() - 10; } +int baz() { return 30; } +\end{codeblocktu} + +Module \tcode{A} contains four translation units: +\begin{itemize} +\item a primary module interface unit, +\item a module partition \tcode{A:Foo}, which is a module interface unit +forming part of the interface of module \tcode{A}, +\item a module partition \tcode{A:Internals}, which does not contribute +to the external interface of module \tcode{A}, and +\item a module implementation unit providing +a definition of \tcode{bar} and \tcode{baz}, +which cannot be imported because +it does not have a partition name. +\end{itemize} +\end{example} + +\pnum +A \defnadj{module unit}{purview} is +the sequence of \grammarterm{token}{s} +starting at the \grammarterm{module-declaration} +and extending to the end of the translation unit. +The \defnx{purview}{purview!named module} +of a named module \tcode{M} is the set of module unit purviews +of \tcode{M}'s module units. + +\pnum +The \defnadj{global}{module} is the collection of all +\grammarterm{global-module-fragment}{s} +and all translation units that are not module units. +Declarations appearing in such a context +are said to be in the \defnx{purview}{purview!global module} of the global module. +\begin{note} +The global module has no name, no module interface unit, and is not +introduced by any \grammarterm{module-declaration}. +\end{note} + +\pnum +A \defn{module} is either a named module or the global module. +A declaration is \defnx{attached}{attached!declaration} to a module as follows: +\begin{itemize} +\item If the declaration +\begin{itemize} +\item is a replaceable global allocation or deallocation +function (\ref{new.delete.single}, \ref{new.delete.array}), or +\item is a \grammarterm{namespace-declaration} with external linkage, or +\item appears within a \grammarterm{linkage-specification}, +\end{itemize} +it is attached to the global module. + +\item Otherwise, the declaration is +attached to the module in whose purview it appears. +\end{itemize} + +\pnum +A \grammarterm{module-declaration} +that contains neither \tcode{export} +nor a \grammarterm{module-partition} +implicitly imports the primary module interface unit of the module +as if by a \grammarterm{module-import-declaration}. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +module B:Y; // does not implicitly import \tcode{B} +int y(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module B; +import :Y; // OK, does not create interface dependency cycle +int n = y(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +module B:X1; // does not implicitly import \tcode{B} +int &a = n; // error: \tcode{n} not visible here +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#4} +module B:X2; // does not implicitly import \tcode{B} +import B; +int &b = n; // OK +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#5} +module B; // implicitly imports \tcode{B} +int &c = n; // OK +\end{codeblocktu} +\end{example} + +\rSec1[module.interface]{Export declaration}% + +\begin{bnf} +\nontermdef{export-declaration}\br + \keyword{export} declaration\br + \keyword{export} \terminal{\{} \opt{declaration-seq} \terminal{\}} +\end{bnf} + +\pnum +An \grammarterm{export-declaration} shall appear only +at namespace scope and only in the purview of a module interface unit. +An \grammarterm{export-declaration} shall not appear directly +or indirectly within an unnamed namespace +or a \grammarterm{private-module-fragment}. +An \grammarterm{export-declaration} +has the declarative effects of its \grammarterm{declaration} +or its \grammarterm{declaration-seq} (if any). +An \grammarterm{export-declaration} does not +establish a scope and its \grammarterm{declaration} +or \grammarterm{declaration-seq} +shall not contain an \grammarterm{export-declaration}. + +\pnum +A declaration is \defnx{exported}{declaration!exported} if it is +\begin{itemize} +\item a namespace-scope declaration declared within an + \grammarterm{export-declaration}, or +\item a \grammarterm{module-import-declaration} declared with + the \tcode{export} keyword\iref{module.import}, or +\item a \grammarterm{namespace-definition} that contains an + exported declaration, or +\item a declaration within a header unit\iref{module.import} + that introduces at least one name. +\end{itemize} +The \defnx{interface}{module!interface} of a module \tcode{M} +is the set of all exported declarations within its purview. +\begin{example} +\begin{codeblock} +export module M; +namespace A { // exported + export int f(); // exported + int g(); // not exported +} +\end{codeblock} +The interface of \tcode{M} comprises \tcode{A} and \tcode{A::f}. +\end{example} + +\pnum +An exported declaration shall declare at least one name. +If the declaration is not within a header unit, +it shall not declare a name with internal linkage. + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"a.h"}} +export int x; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#1} +module; +#include "a.h" // error: declaration of \tcode{x} is not in the + // purview of a module interface unit +export module M; +export namespace {} // error: does not introduce any names +export namespace { + int a1; // error: export of name with internal linkage +} +namespace { + export int a2; // error: export of name with internal linkage +} +export static int b; // error: b explicitly declared static +export int f(); // OK +export namespace N { } // OK +export using namespace N; // error: does not declare a name +\end{codeblocktu} +\end{example} + +\pnum +If the declaration is a \grammarterm{using-declaration}\iref{namespace.udecl} +and is not within a header unit, +all entities to which all of the +\grammarterm{using-declarator}{s} ultimately refer (if any) +shall have been introduced with a name having external linkage. +\begin{example} +\begin{codeblocktu}{Source file \tcode{"b.h"}} +int f(); +\end{codeblocktu} + +\begin{codeblocktu}{Importable header \tcode{"c.h"}} +int g(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#1} +export module X; +export int h(); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +module; +#include "b.h" +export module M; +import "c.h"; +import X; +export using ::f, ::g, ::h; // OK +struct S; +export using ::S; // error: \tcode{S} has module linkage +namespace N { + export int h(); + static int h(int); // \#1 +} +export using N::h; // error: \#1 has internal linkage +\end{codeblocktu} +\end{example} +\begin{note} +These constraints do not apply to +type names introduced by \tcode{typedef} declarations +and \grammarterm{alias-declaration}{s}. +\begin{example} +\begin{codeblock} +export module M; +struct S; +export using T = S; // OK, exports name \tcode{T} denoting type \tcode{S} +\end{codeblock} +\end{example} +\end{note} + +\pnum +A redeclaration of an exported declaration of an entity +is implicitly exported. +An exported redeclaration of a non-exported declaration +of an entity is ill-formed. +\begin{example} +\begin{codeblock} +export module M; +struct S { int n; }; +typedef S S; +export typedef S S; // OK, does not redeclare an entity +export struct S; // error: exported declaration follows non-exported declaration +\end{codeblock} +\end{example} + +\pnum +A name is \defnx{exported}{name!exported} by a module +if it is introduced or redeclared +by an exported declaration in the purview of that module. +\begin{note} +Exported names have either external linkage or no linkage; see \ref{basic.link}. +Namespace-scope names exported by a module are visible to name lookup +in any translation unit importing that module; see \ref{basic.scope.namespace}. +Class and enumeration member names are visible to name lookup in any +context in which a definition of the type is reachable. +\end{note} +\begin{example} +\begin{codeblocktu}{Interface unit of \tcode{M}} +export module M; +export struct X { + static void f(); + struct Y { }; +}; + +namespace { + struct S { }; +} +export void f(S); // OK +struct T { }; +export T id(T); // OK + +export struct A; // \tcode{A} exported as incomplete + +export auto rootFinder(double a) { + return [=](double x) { return (x + a/x)/2; }; +} + +export const int n = 5; // OK, \tcode{n} has external linkage +\end{codeblocktu} + +\begin{codeblocktu}{Implementation unit of \tcode{M}} +module M; +struct A { + int value; +}; +\end{codeblocktu} + +\begin{codeblocktu}{Main program} +import M; +int main() { + X::f(); // OK, \tcode{X} is exported and definition of \tcode{X} is reachable + X::Y y; // OK, \tcode{X::Y} is exported as a complete type + auto f = rootFinder(2); // OK + return A{45}.value; // error: \tcode{A} is incomplete +} +\end{codeblocktu} +\end{example} + +\pnum +\begin{note} +Redeclaring a name in an \grammarterm{export-declaration} +cannot change the linkage of the name\iref{basic.link}. +\begin{example} +\begin{codeblocktu}{Interface unit of \tcode{M}} +export module M; +static int f(); // \#1 +export int f(); // error: \#1 gives internal linkage +struct S; // \#2 +export struct S; // error: \#2 gives module linkage +namespace { + namespace N { + extern int x; // \#3 + } +} +export int N::x; // error: \#3 gives internal linkage +\end{codeblocktu} +\end{example} +\end{note} + +\pnum +\begin{note} +Declarations in an exported \grammarterm{namespace-definition} +or in an exported \grammarterm{linkage-specification}\iref{dcl.link} +are exported and subject to the rules of exported declarations. +\begin{example} +\begin{codeblock} +export module M; +export namespace N { + int x; // OK + static_assert(1 == 1); // error: does not declare a name +} +\end{codeblock} +\end{example} +\end{note} + +\rSec1[module.import]{Import declaration}% + +\begin{bnf} +\nontermdef{module-import-declaration}\br + \opt{\keyword{export}} \keyword{import} module-name \opt{attribute-specifier-seq} \terminal{;}\br + \opt{\keyword{export}} \keyword{import} module-partition \opt{attribute-specifier-seq} \terminal{;}\br + \opt{\keyword{export}} \keyword{import} header-name \opt{attribute-specifier-seq} \terminal{;} +\end{bnf} + +\pnum +In a module unit, all \grammarterm{module-import-declaration}{s} +shall precede all other \grammarterm{top-level-declaration}{s} in +the \grammarterm{top-level-declaration-seq} of the +\grammarterm{translation-unit} +and of the \grammarterm{private-module-fragment} (if any). +The optional \grammarterm{attribute-specifier-seq} +appertains to the \grammarterm{module-import-declaration}. + +\pnum +A \grammarterm{module-import-declaration} \defnx{imports}{import} a set of +translation units determined as described below. +\begin{note} +Namespace-scope names exported by the imported translation units +become visible\iref{basic.scope.namespace} +in the importing translation unit +and declarations within the imported translation units +become reachable\iref{module.reach} +in the importing translation unit +after the import declaration. +\end{note} + +\pnum +A \grammarterm{module-import-declaration} that specifies +a \grammarterm{module-name} \tcode{M} +imports all module interface units of \tcode{M}. + +\pnum +A \grammarterm{module-import-declaration} that specifies +a \grammarterm{module-partition} shall only appear after +the \grammarterm{module-declaration} in a module unit of +some module \tcode{M}. +Such a declaration imports the so-named +module partition of \tcode{M}. + +\pnum +A \grammarterm{module-import-declaration} that specifies +a \grammarterm{header-name} \tcode{H} imports +a synthesized \defn{header unit}, +which is a translation unit formed by applying +phases 1 to 7 of translation\iref{lex.phases} +to the source file or header nominated by \tcode{H}, +which shall not contain a \grammarterm{module-declaration}. +\begin{note} +All declarations within a header unit are implicitly +exported\iref{module.interface}, +and are attached to the global module\iref{module.unit}. +\end{note} +An \defnadj{importable}{header} is a member of an +\impldef{how the set of importable headers is determined} +set of headers. +\tcode{H} shall identify an importable header. +Two +\grammarterm{module-import-declaration}{s} +import the same header unit if and only if +their \grammarterm{header-name}{s} identify the same +header or source file\iref{cpp.include}. +\begin{note} +A \grammarterm{module-import-declaration} nominating +a \grammarterm{header-name} is also recognized by the +preprocessor, and results in macros defined at the +end of phase 4 of translation of the header unit +being made visible as described in \ref{cpp.module}. +\end{note} +A declaration of a name with internal linkage is +permitted within a header unit despite all +declarations being implicitly exported\iref{module.interface}. +If such a declaration declares an entity +that is odr-used outside the +header unit, or by a template +instantiation whose point of instantiation is outside +the header unit, the program is ill-formed. + +\pnum +When a \grammarterm{module-import-declaration} imports +a translation unit $T$, it also imports +all translation units imported by +exported \grammarterm{module-import-declaration}{s} +in $T$; such translation units are +said to be \defnx{exported}{module!exported} by $T$. +When a \grammarterm{module-import-declaration} in a module unit imports +another module unit of the same module, it also imports +all translation units imported by +all \grammarterm{module-import-declaration}{s} +in that module unit. +These rules may in turn lead to the importation of yet more +translation units. + +\pnum +A module implementation unit shall not be exported. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +module M:Part; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module M; +export import :Part; // error: exported partition \tcode{:Part} is an implementation unit +\end{codeblocktu} +\end{example} + +\pnum +A module implementation unit of a module \tcode{M} +that is not a module partition +shall not contain a \grammarterm{module-import-declaration} +nominating \tcode{M}. +\begin{example} +\begin{codeblock} +module M; +import M; // error: cannot import \tcode{M} in its own unit +\end{codeblock} +\end{example} + +\pnum +A translation unit has an \defn{interface dependency} on a module unit \tcode{U} +if it contains a \grammarterm{module-declaration} or +\grammarterm{module-import-declaration} that imports \tcode{U} or if it has +an interface dependency on a module unit that has an interface dependency on \tcode{U}. +A translation unit shall not have an interface dependency on itself. +\begin{example} +\begin{codeblocktu}{Interface unit of \tcode{M1}} +export module M1; +import M2; +\end{codeblocktu} + +\begin{codeblocktu}{Interface unit of \tcode{M2}} +export module M2; +import M3; +\end{codeblocktu} + +\begin{codeblocktu}{Interface unit of \tcode{M3}} +export module M3; +import M1; // error: cyclic interface dependency $\mathtt{M3} \rightarrow \mathtt{M1} \rightarrow \mathtt{M2} \rightarrow \mathtt{M3}$ +\end{codeblocktu} +\end{example} + +\rSec1[module.global]{Global module fragment} + +\begin{bnf} +\nontermdef{global-module-fragment}\br + \keyword{module} \terminal{;} \opt{top-level-declaration-seq} +\end{bnf} + +\pnum +A \grammarterm{global-module-fragment} specifies the contents of the +\defn{global module fragment} for a module unit. +The global module fragment can be used to provide declarations +that are attached to the global module and usable within the module unit. +\begin{note} +Prior to phase 4 of translation, +only preprocessing directives can appear +in the global module fragment\iref{cpp.glob.frag}. +\end{note} + +\pnum +A declaration $D$ is \defn{decl-reachable} from a declaration $S$ +in the same translation unit if: +\begin{itemize} +\item +$D$ does not declare a function or function template and +$S$ contains an +\grammarterm{id-expression}, +\grammarterm{namespace-name}, +\grammarterm{type-name}, +\grammarterm{template-name}, or +\grammarterm{concept-name} +naming $D$, or + +\item +$D$ declares a function or function template that +is named by an expression\iref{basic.def.odr} +appearing in $S$, or + +\item +$S$ contains an expression \tcode{E} of the form + +\begin{ncsimplebnf} +postfix-expression \terminal{(} \opt{expression-list} \terminal{)} +\end{ncsimplebnf} +whose \grammarterm{postfix-expression} denotes a dependent name, +or for an operator expression whose operator denotes a dependent name, +and $D$ is found by name lookup for the corresponding name +in an expression synthesized from \tcode{E} +by replacing each type-dependent argument or operand +with a value of a placeholder type +with no associated namespaces or entities, or + +\item +$S$ contains an expression that +takes the address of an overloaded function\iref{over.over} +whose set of overloads contains $D$ and +for which the target type is dependent, or + +\item +there exists a declaration $M$ that is not a \grammarterm{namespace-definition} +for which $M$ is decl-reachable from $S$ and either +\begin{itemize} +\item +$D$ is decl-reachable from $M$, or +\item +$D$ redeclares the entity declared by $M$ or +$M$ redeclares the entity declared by $D$, +and $D$ is neither a friend declaration +nor a block-scope declaration, or +\item +$D$ declares a namespace $N$ and $M$ is a member of $N$, or +\item +one of $M$ and $D$ declares a class or class template $C$ +and the other declares a member or friend of $C$, or +\item +one of $D$ and $M$ declares an enumeration $E$ +and the other declares an enumerator of $E$, or +\item +$D$ declares a function or variable and $M$ is declared in $D$,% +\footnote{A declaration can appear within a \grammarterm{lambda-expression} +in the initializer of a variable.} or +\item +one of $M$ and $D$ declares a template and the other declares +a partial or explicit specialization or +an implicit or explicit instantiation of that template, or +\item +one of $M$ and $D$ declares a class or enumeration type +and the other introduces a typedef name for linkage purposes for that type. +\end{itemize} +\end{itemize} +In this determination, it is unspecified +\begin{itemize} +\item +whether a reference to an +\grammarterm{alias-declaration}, +\tcode{typedef} declaration, +\grammarterm{using-declaration}, or +\grammarterm{namespace-alias-declaration} +is replaced by the declarations they name +prior to this determination, + +\item +whether a \grammarterm{simple-template-id} +that does not denote a dependent type +and whose \grammarterm{template-name} names an alias template +is replaced by its denoted type +prior to this determination, + +\item +whether a \grammarterm{decltype-specifier} +that does not denote a dependent type +is replaced by its denoted type +prior to this determination, +and + +\item +whether a non-value-dependent constant expression +is replaced by the result of constant evaluation +prior to this determination. +\end{itemize} + +\pnum +A declaration \tcode{D} in a global module fragment of a module unit +is \defnx{discarded}{discarded!declaration} if \tcode{D} +is not decl-reachable from any \grammarterm{top-level-declaration} +in the \grammarterm{top-level-declaration-seq} +of the \grammarterm{translation unit}. +\begin{note} +A discarded declaration is neither reachable +nor visible to name lookup outside the module unit, +nor in template instantiations whose points of instantiation\iref{temp.point} +are outside the module unit, +even when the instantiation context\iref{module.context} +includes the module unit. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +const int size = 2; +int ary1[size]; // unspecified whether \tcode{size} is decl-reachable from \tcode{ary1} +constexpr int identity(int x) { return x; } +int ary2[identity(2)]; // unspecified whether \tcode{identity} is decl-reachable from \tcode{ary2} + +template struct S; +template struct S2; +constexpr int g(int); + +template +S> f(); // \tcode{S}, \tcode{S2}, \tcode{g}, and \tcode{::} are decl-reachable from \tcode{f} + +template +void h() noexcept(g(N) == N); // \tcode{g} and \tcode{::} are decl-reachable from \tcode{h} +\end{codeblock} +\end{example} + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"foo.h"}} +namespace N { + struct X {}; + int d(); + int e(); + inline int f(X, int = d()) { return e(); } + int g(X); + int h(X); +} +\end{codeblocktu} + +\begin{codeblocktu}{Module \tcode{M} interface} +module; +#include "foo.h" +export module M; +template int use_f() { + N::X x; // \tcode{N::X}, \tcode{N}, and \tcode{::} are decl-reachable from \tcode{use_f} + return f(x, 123); // \tcode{N::f} is decl-reachable from \tcode{use_f}, + // \tcode{N::e} is indirectly decl-reachable from \tcode{use_f} + // because it is decl-reachable from \tcode{N::f}, and + // \tcode{N::d} is decl-reachable from \tcode{use_f} + // because it is decl-reachable from \tcode{N::f} + // even though it is not used in this call +} +template int use_g() { + N::X x; // \tcode{N::X}, \tcode{N}, and \tcode{::} are decl-reachable from \tcode{use_f} + return g((T(), x)); // \tcode{N::g} is not decl-reachable from \tcode{use_g} +} +template int use_h() { + N::X x; // \tcode{N::X}, \tcode{N}, and \tcode{::} are decl-reachable from \tcode{use_h} + return h((T(), x)); // \tcode{N::h} is not decl-reachable from \tcode{use_h}, but + // \tcode{N::h} is decl-reachable from \tcode{use_h} +} +int k = use_h(); + // \tcode{use_h} is decl-reachable from \tcode{k}, so + // \tcode{N::h} is decl-reachable from \tcode{k} +\end{codeblocktu} + +\begin{codeblocktu}{Module \tcode{M} implementation} +module M; +int a = use_f(); // OK +int b = use_g(); // error: no viable function for call to \tcode{g}; + // \tcode{g} is not decl-reachable from purview of + // module \tcode{M}{'s} interface, so is discarded +int c = use_h(); // OK +\end{codeblocktu} +\end{example} + +\rSec1[module.context]{Instantiation context} + +\pnum +The \defn{instantiation context} is a set of points within the program +that determines which names are visible +to argument-dependent name lookup\iref{basic.lookup.argdep} +and which declarations are reachable\iref{module.reach} +in the context of a particular declaration or template instantiation. + +\pnum +During the implicit definition of +a defaulted special member function\iref{special}, +the instantiation context is the union of +the instantiation context from the definition of the class and +the instantiation context of the program construct that +resulted in the implicit definition of the special member function. + +\pnum +During the implicit instantiation of a template +whose point of instantiation is specified as +that of an enclosing specialization\iref{temp.point}, +the instantiation context is the union of +the instantiation context of the enclosing specialization and, +if the template is defined in a module interface unit of a module $M$ +and the point of instantiation is not in a module interface unit of $M$, +the point at the end of the +\grammarterm{top-level-declaration-seq} of the +primary module interface unit of $M$ +(prior to the \grammarterm{private-module-fragment}, if any). + +\pnum +During the implicit instantiation of a template +that is implicitly instantiated because it is referenced +from within the implicit definition of a defaulted special member function, +the instantiation context is the instantiation context of +the defaulted special member function. + +\pnum +During the instantiation of any other template specialization, +the instantiation context comprises the point of instantiation +of the template. + +\pnum +In any other case, the instantiation context +at a point within the program +comprises that point. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module stuff; +export template void foo(T, U u) { auto v = u; } +export template void bar(T, U u) { auto v = *u; } +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module M1; +import "defn.h"; // provides \tcode{struct X \{\};} +import stuff; +export template void f(T t) { + X x; + foo(t, x); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +export module M2; +import "decl.h"; // provides \tcode{struct X;} (not a definition) +import stuff; +export template void g(T t) { + X *x; + bar(t, x); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#4} +import M1; +import M2; +void test() { + f(0); + g(0); +} +\end{codeblocktu} +The call to \tcode{f(0)} is valid; +the instantiation context of \tcode{foo} comprises +\begin{itemize} +\item the point at the end of translation unit \#1, +\item the point at the end of translation unit \#2, and +\item the point of the call to \tcode{f(0)}, +\end{itemize} +so the definition of \tcode{X} is reachable (\ref{module.reach}). + +It is unspecified whether the call to \tcode{g(0)} is valid: +the instantiation context of \tcode{bar} comprises +\begin{itemize} +\item the point at the end of translation unit \#1, +\item the point at the end of translation unit \#3, and +\item the point of the call to \tcode{g(0)}, +\end{itemize} +so the definition of \tcode{X} is not necessarily reachable, +as described in \ref{module.reach}. +\end{example} + +\rSec1[module.reach]{Reachability} + +\indextext{necessarily reachable|see{reachable!necessarily}} +\pnum +A translation unit $U$ is +\defnx{necessarily reachable}{reachable!necessarily!translation unit} +from a point $P$ if +$U$ is a module interface unit on which the translation unit containing $P$ +has an interface dependency, or +the translation unit containing $P$ imports $U$, +in either case prior to $P$ (\ref{module.import}). +\begin{note} +While module interface units are reachable even when they are only +transitively imported via a non-exported import declaration, +namespace-scope names from such module interface units are not visible +to name lookup\iref{basic.scope.namespace}. +\end{note} + +\pnum +All translation units that are necessarily reachable are +\defnx{reachable}{reachable!translation unit}. +It is unspecified whether additional translation units on which the +point within the program has an interface dependency are considered reachable, +and under what circumstances.% +\footnote{Implementations are therefore not required to prevent the semantic +effects of additional translation units involved in the compilation from being +observed.} +\begin{note} +It is advisable to avoid +depending on the reachability of any additional translation units +in programs intending to be portable. +\end{note} + +\pnum +A declaration $D$ is +\defnx{reachable}{reachable!declaration} or +\defnx{necessarily reachable}{reachable!necessarily!declaration}, +respectively, if, +for any point $P$ in the +instantiation context\iref{module.context}, +\begin{itemize} +\item $D$ appears prior to $P$ in the same translation unit, or +\item $D$ is not discarded\iref{module.global}, +appears in a translation unit that is +reachable or necessarily reachable from $P$, respectively, +and +either does not appear within a \grammarterm{private-module-fragment} +or appears in a \grammarterm{private-module-fragment} +of the module containing $P$. +\end{itemize} +\begin{note} +Whether a declaration is exported has no bearing on whether it is reachable. +\end{note} + +\pnum +The accumulated properties of all reachable declarations of +an entity within a context +determine the behavior of the entity within that context. +\begin{note} +These reachable semantic properties include type completeness, +type definitions, initializers, +default arguments of functions or template declarations, attributes, +visibility of class or enumeration member names to ordinary lookup, +etc. +Since default arguments are evaluated in the context of the call expression, +the reachable semantic properties of the corresponding parameter types apply in +that context. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M:A; +export struct B; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +module M:B; +struct B { + operator int(); +}; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +module M:C; +import :A; +B b1; // error: no reachable definition of \tcode{struct B} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#4} +export module M; +export import :A; +import :B; +B b2; +export void f(B b = B()); +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#5} +module X; +import M; +B b3; // error: no reachable definition of \tcode{struct B} +void g() { f(); } // error: no reachable definition of \tcode{struct B} +\end{codeblocktu} +\end{example} +\end{note} + +\pnum +\begin{note} +An entity can have reachable declarations +even if it is not visible to name lookup. +\end{note} +\begin{example} +\begin{codeblock} +export module A; +struct X {}; +export using Y = X; + +module B; +import A; +Y y; // OK, definition of \tcode{X} is reachable +X x; // ill-formed: \tcode{X} not visible to unqualified lookup +\end{codeblock} +\end{example} diff --git a/source/numerics.tex b/source/numerics.tex index 7f85dc7b2e..b948bceed7 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -36,10 +36,15 @@ and \tcode{valarray} components are parameterized by the type of information they contain and manipulate. -A \Cpp{} program shall instantiate these components only with a type -\tcode{T} +A \Cpp{} program shall instantiate these components only with a numeric type. +A \defnadj{numeric}{type} is a cv-unqualified object type \tcode{T} that satisfies the -following requirements:\footnote{In other words, value types. +\oldconcept{DefaultConstructible}, +\oldconcept{CopyConstructible}, +\oldconcept{CopyAssignable}, and +\oldconcept{Destructible} +requirements\iref{utility.arg.requirements}.% +\footnote{In other words, value types. These include arithmetic types, pointers, the library class \tcode{complex}, @@ -47,60 +52,6 @@ \tcode{valarray} for value types.} -\begin{itemize} -\item \tcode{T} is not an abstract class (it has no pure virtual member functions); -\item \tcode{T} is not a reference type; -\item \tcode{T} is not cv-qualified; -\item If \tcode{T} is a class, it has a public default constructor; -\item If \tcode{T} is a class, it has a public copy constructor with the signature \tcode{T::T(const T\&)} -\item If \tcode{T} is a class, it has a public destructor; -\item If \tcode{T} is a class, it has a public assignment operator whose signature is either -\tcode{T\& T::operator=(const T\&)} -or -\tcode{T\& T::operator=(T)} -\item If \tcode{T} is a class, its assignment operator, copy and default constructors, -and destructor shall correspond to each other in the following sense: - \begin{itemize} - \item Initialization of raw storage using the copy constructor - on the value of \tcode{T()}, however obtained, - is semantically equivalent to value-initialization of the same raw storage. - \item Initialization of raw storage using the default constructor, - followed by assignment, - is semantically equivalent to initialization of raw storage using the copy constructor. - \item Destruction of an object, - followed by initialization of its raw storage using the copy constructor, - is semantically equivalent to assignment to the original object. - \end{itemize} - -\begin{note} -This rule states, in part, that there shall not be any subtle differences in the semantics -of initialization versus assignment. -This gives an implementation -considerable flexibility in how arrays are initialized. - -\begin{example} -An implementation is allowed to initialize a -\tcode{valarray} -by allocating storage using the -\tcode{new} -operator (which -implies a call to the default constructor for each element) and then -assigning each element its value. -Or the implementation can allocate raw -storage and use the copy constructor to initialize each element. -\end{example} - -If the distinction between initialization and assignment is important -for a class, or if it fails to satisfy any of -the other conditions listed above, the programmer should use -\tcode{vector}\iref{vector} instead of -\tcode{valarray} -for that class. -\end{note} -\item If \tcode{T} is a class, it does not overload unary -\tcode{operator\&}. -\end{itemize} - \pnum If any operation on \tcode{T} throws an exception the effects are undefined. @@ -3966,8 +3917,7 @@ \begin{itemdescr} \pnum\returns A nondeterministic random value, uniformly distributed - between \tcode{min()} and \tcode{max()}, - inclusive. + between \tcode{min()} and \tcode{max()} (inclusive). It is \impldef{how \tcode{random_device::operator()} generates values} how these values are generated. @@ -7026,12 +6976,12 @@ \pnum \remarks -The expression \tcode{\&a[i+j] == \&a[i] + j} +The expression \tcode{addressof(a[i+j]) == addressof(a[i]) + j} evaluates to \tcode{true} for all \tcode{size_t i} and \tcode{size_t j} such that \tcode{i+j < a.size()}. \pnum -The expression \tcode{\&a[i] != \&b[j]} +The expression \tcode{addressof(a[i]) != addressof(b[j])} evaluates to \tcode{true} for any two arrays \tcode{a} and \tcode{b} and for any \tcode{size_t i} and \tcode{size_t j} @@ -9168,6 +9118,11 @@ float fmaf(float x, float y, float z); long double fmal(long double x, long double y, long double z); + // \ref{c.math.lerp}, linear interpolation + constexpr float lerp(float a, float b, float t); + constexpr double lerp(double a, double b, double t); + constexpr long double lerp(long double a, long double b, long double t); + // \ref{c.math.fpclass}, classification / comparison functions int fpclassify(float x); int fpclassify(double x); @@ -9219,12 +9174,12 @@ // \ref{sf.cmath}, mathematical special functions - // \ref{sf.cmath.assoc_laguerre}, associated Laguerre polynomials + // \ref{sf.cmath.assoc.laguerre}, associated Laguerre polynomials double assoc_laguerre(unsigned n, unsigned m, double x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x); - // \ref{sf.cmath.assoc_legendre}, associated Legendre functions + // \ref{sf.cmath.assoc.legendre}, associated Legendre functions double assoc_legendre(unsigned l, unsigned m, double x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x); @@ -9234,53 +9189,53 @@ float betaf(float x, float y); long double betal(long double x, long double y); - // \ref{sf.cmath.comp_ellint_1}, complete elliptic integral of the first kind + // \ref{sf.cmath.comp.ellint.1}, complete elliptic integral of the first kind double comp_ellint_1(double k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k); - // \ref{sf.cmath.comp_ellint_2}, complete elliptic integral of the second kind + // \ref{sf.cmath.comp.ellint.2}, complete elliptic integral of the second kind double comp_ellint_2(double k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k); - // \ref{sf.cmath.comp_ellint_3}, complete elliptic integral of the third kind + // \ref{sf.cmath.comp.ellint.3}, complete elliptic integral of the third kind double comp_ellint_3(double k, double nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu); - // \ref{sf.cmath.cyl_bessel_i}, regular modified cylindrical Bessel functions + // \ref{sf.cmath.cyl.bessel.i}, regular modified cylindrical Bessel functions double cyl_bessel_i(double nu, double x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x); - // \ref{sf.cmath.cyl_bessel_j}, cylindrical Bessel functions of the first kind + // \ref{sf.cmath.cyl.bessel.j}, cylindrical Bessel functions of the first kind double cyl_bessel_j(double nu, double x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x); - // \ref{sf.cmath.cyl_bessel_k}, irregular modified cylindrical Bessel functions + // \ref{sf.cmath.cyl.bessel.k}, irregular modified cylindrical Bessel functions double cyl_bessel_k(double nu, double x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x); - // \ref{sf.cmath.cyl_neumann}, cylindrical Neumann functions; + // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions; // cylindrical Bessel functions of the second kind double cyl_neumann(double nu, double x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x); - // \ref{sf.cmath.ellint_1}, incomplete elliptic integral of the first kind + // \ref{sf.cmath.ellint.1}, incomplete elliptic integral of the first kind double ellint_1(double k, double phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi); - // \ref{sf.cmath.ellint_2}, incomplete elliptic integral of the second kind + // \ref{sf.cmath.ellint.2}, incomplete elliptic integral of the second kind double ellint_2(double k, double phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi); - // \ref{sf.cmath.ellint_3}, incomplete elliptic integral of the third kind + // \ref{sf.cmath.ellint.3}, incomplete elliptic integral of the third kind double ellint_3(double k, double nu, double phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi); @@ -9305,22 +9260,22 @@ float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x); - // \ref{sf.cmath.riemann_zeta}, Riemann zeta function + // \ref{sf.cmath.riemann.zeta}, Riemann zeta function double riemann_zeta(double x); float riemann_zetaf(float x); long double riemann_zetal(long double x); - // \ref{sf.cmath.sph_bessel}, spherical Bessel functions of the first kind + // \ref{sf.cmath.sph.bessel}, spherical Bessel functions of the first kind double sph_bessel(unsigned n, double x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x); - // \ref{sf.cmath.sph_legendre}, spherical associated Legendre functions + // \ref{sf.cmath.sph.legendre}, spherical associated Legendre functions double sph_legendre(unsigned l, unsigned m, double theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta); - // \ref{sf.cmath.sph_neumann}, spherical Neumann functions; + // \ref{sf.cmath.sph.neumann}, spherical Neumann functions; // spherical Bessel functions of the second kind double sph_neumann(unsigned n, double x); float sph_neumannf(unsigned n, float x); @@ -9424,6 +9379,39 @@ \returns $\sqrt{x^2+y^2+z^2}$. \end{itemdescr} +\rSec2[c.math.lerp]{Linear interpolation} + +\indexlibrary{\idxcode{lerp}}% +\begin{itemdecl} +constexpr float lerp(float a, float b, float t); +constexpr double lerp(double a, double b, double t); +constexpr long double lerp(long double a, long double b, long double t); +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +$a+t(b-a)$. + +\pnum +\remarks +Let \tcode{r} be the value returned. +If \tcode{isfinite(a) \&\& isfinite(b)}, then: +\begin{itemize} +\item If \tcode{t == 0}, then \tcode{r == a}. +\item If \tcode{t == 1}, then \tcode{r == b}. +\item If \tcode{t >= 0 \&\& t <= 1}, then \tcode{isfinite(r)}. +\item If \tcode{isfinite(t) \&\& a == b}, then \tcode{r == a}. +\item If \tcode{isfinite(t) || !isnan(t) \&\& b-a != 0}, then \tcode{!isnan(r)}. +\end{itemize} +Let \tcode{\placeholder{CMP}(x,y)} be \tcode{1} if \tcode{x > y}, +\tcode{-1} if \tcode{x < y}, and \tcode{0} otherwise. +For any \tcode{t1} and \tcode{t2}, the product of +\tcode{\placeholder{CMP}(lerp(a, b, t2), lerp(a, b, t1))}, +\tcode{\placeholder{CMP}(t2, t1)}, and +\tcode{\placeholder{CMP}(b, a)} +is non-negative. +\end{itemdescr} + \rSec2[c.math.fpclass]{Classification / comparison functions} \pnum @@ -9484,7 +9472,7 @@ for negative infinity, and for positive infinity. -\rSec3[sf.cmath.assoc_laguerre]{Associated Laguerre polynomials}% +\rSec3[sf.cmath.assoc.laguerre]{Associated Laguerre polynomials}% \indexlibrary{\idxcode{assoc_laguerre}}% \indexlibrary{\idxcode{assoc_laguerref}}% \indexlibrary{\idxcode{assoc_laguerrel}}% @@ -9521,7 +9509,7 @@ if \tcode{n >= 128} or if \tcode{m >= 128}. \end{itemdescr} -\rSec3[sf.cmath.assoc_legendre]{Associated Legendre functions}% +\rSec3[sf.cmath.assoc.legendre]{Associated Legendre functions}% \indexlibrary{\idxcode{assoc_legendre}}% \indexlibrary{\idxcode{assoc_legendref}}% \indexlibrary{\idxcode{assoc_legendrel}}% @@ -9587,7 +9575,7 @@ $y$ is \tcode{y}. \end{itemdescr} -\rSec3[sf.cmath.comp_ellint_1]{Complete elliptic integral of the first kind}% +\rSec3[sf.cmath.comp.ellint.1]{Complete elliptic integral of the first kind}% \indexlibrary{\idxcode{comp_ellint_1}}% \indexlibrary{\idxcode{comp_ellint_1f}}% \indexlibrary{\idxcode{comp_ellint_1l}}% @@ -9614,10 +9602,10 @@ $k$ is \tcode{k}. \pnum -See also \ref{sf.cmath.ellint_1}. +See also \ref{sf.cmath.ellint.1}. \end{itemdescr} -\rSec3[sf.cmath.comp_ellint_2]{Complete elliptic integral of the second kind}% +\rSec3[sf.cmath.comp.ellint.2]{Complete elliptic integral of the second kind}% \indexlibrary{\idxcode{comp_ellint_2}}% \indexlibrary{\idxcode{comp_ellint_2f}}% \indexlibrary{\idxcode{comp_ellint_2l}}% @@ -9644,10 +9632,10 @@ $k$ is \tcode{k}. \pnum -See also \ref{sf.cmath.ellint_2}. +See also \ref{sf.cmath.ellint.2}. \end{itemdescr} -\rSec3[sf.cmath.comp_ellint_3]{Complete elliptic integral of the third kind}% +\rSec3[sf.cmath.comp.ellint.3]{Complete elliptic integral of the third kind}% \indexlibrary{\idxcode{comp_ellint_3}}% \indexlibrary{\idxcode{comp_ellint_3f}}% \indexlibrary{\idxcode{comp_ellint_3l}}% @@ -9675,10 +9663,10 @@ $\nu$ is \tcode{nu}. \pnum -See also \ref{sf.cmath.ellint_3}. +See also \ref{sf.cmath.ellint.3}. \end{itemdescr} -\rSec3[sf.cmath.cyl_bessel_i]{Regular modified cylindrical Bessel functions}% +\rSec3[sf.cmath.cyl.bessel.i]{Regular modified cylindrical Bessel functions}% \indexlibrary{\idxcode{cyl_bessel_i}}% \indexlibrary{\idxcode{cyl_bessel_if}}% \indexlibrary{\idxcode{cyl_bessel_il}}% @@ -9715,10 +9703,10 @@ if \tcode{nu >= 128}. \pnum -See also \ref{sf.cmath.cyl_bessel_j}. +See also \ref{sf.cmath.cyl.bessel.j}. \end{itemdescr} -\rSec3[sf.cmath.cyl_bessel_j]{Cylindrical Bessel functions of the first kind}% +\rSec3[sf.cmath.cyl.bessel.j]{Cylindrical Bessel functions of the first kind}% \indexlibrary{\idxcode{cyl_bessel_j}}% \indexlibrary{\idxcode{cyl_bessel_jf}}% \indexlibrary{\idxcode{cyl_bessel_jl}}% @@ -9752,7 +9740,7 @@ if \tcode{nu >= 128}. \end{itemdescr} -\rSec3[sf.cmath.cyl_bessel_k]{Irregular modified cylindrical Bessel functions}% +\rSec3[sf.cmath.cyl.bessel.k]{Irregular modified cylindrical Bessel functions}% \indexlibrary{\idxcode{cyl_bessel_k}}% \indexlibrary{\idxcode{cyl_bessel_kf}}% \indexlibrary{\idxcode{cyl_bessel_kl}}% @@ -9805,10 +9793,10 @@ is \impldef{effect of calling irregular modified cylindrical Bessel functions with \tcode{nu >= 128}} if \tcode{nu >= 128}. -\pnum See also \ref{sf.cmath.cyl_bessel_i}, \ref{sf.cmath.cyl_bessel_j}, \ref{sf.cmath.cyl_neumann}. +\pnum See also \ref{sf.cmath.cyl.bessel.i}, \ref{sf.cmath.cyl.bessel.j}, \ref{sf.cmath.cyl.neumann}. \end{itemdescr} -\rSec3[sf.cmath.cyl_neumann]{Cylindrical Neumann functions}% +\rSec3[sf.cmath.cyl.neumann]{Cylindrical Neumann functions}% \indexlibrary{\idxcode{cyl_neumann}}% \indexlibrary{\idxcode{cyl_neumannf}}% \indexlibrary{\idxcode{cyl_neumannl}}% @@ -9856,10 +9844,10 @@ is \impldef{effect of calling cylindrical Neumann functions with \tcode{nu >= 128}} if \tcode{nu >= 128}. -\pnum See also \ref{sf.cmath.cyl_bessel_j}. +\pnum See also \ref{sf.cmath.cyl.bessel.j}. \end{itemdescr} -\rSec3[sf.cmath.ellint_1]{Incomplete elliptic integral of the first kind}% +\rSec3[sf.cmath.ellint.1]{Incomplete elliptic integral of the first kind}% \indexlibrary{\idxcode{ellint_1}}% \indexlibrary{\idxcode{ellint_1f}}% \indexlibrary{\idxcode{ellint_1l}}% @@ -9889,7 +9877,7 @@ $\phi$ is \tcode{phi}. \end{itemdescr} -\rSec3[sf.cmath.ellint_2]{Incomplete elliptic integral of the second kind}% +\rSec3[sf.cmath.ellint.2]{Incomplete elliptic integral of the second kind}% \indexlibrary{\idxcode{ellint_2}}% \indexlibrary{\idxcode{ellint_2f}}% \indexlibrary{\idxcode{ellint_2l}}% @@ -9918,7 +9906,7 @@ $\phi$ is \tcode{phi}. \end{itemdescr} -\rSec3[sf.cmath.ellint_3]{Incomplete elliptic integral of the third kind}% +\rSec3[sf.cmath.ellint.3]{Incomplete elliptic integral of the third kind}% \indexlibrary{\idxcode{ellint_3}}% \indexlibrary{\idxcode{ellint_3f}}% \indexlibrary{\idxcode{ellint_3l}}% @@ -10085,7 +10073,7 @@ if \tcode{l >= 128}. \end{itemdescr} -\rSec3[sf.cmath.riemann_zeta]{Riemann zeta function}% +\rSec3[sf.cmath.riemann.zeta]{Riemann zeta function}% \indexlibrary{\idxcode{riemann_zeta}}% \indexlibrary{\idxcode{riemann_zetaf}}% \indexlibrary{\idxcode{riemann_zetal}}% @@ -10131,7 +10119,7 @@ $x$ is \tcode{x}. \end{itemdescr} -\rSec3[sf.cmath.sph_bessel]{Spherical Bessel functions of the first kind}% +\rSec3[sf.cmath.sph.bessel]{Spherical Bessel functions of the first kind}% \indexlibrary{\idxcode{sph_bessel}}% \indexlibrary{\idxcode{sph_besself}}% \indexlibrary{\idxcode{sph_bessell}}% @@ -10163,10 +10151,10 @@ is \impldef{effect of calling spherical Bessel functions with \tcode{n >= 128}} if \tcode{n >= 128}. -\pnum See also \ref{sf.cmath.cyl_bessel_j}. +\pnum See also \ref{sf.cmath.cyl.bessel.j}. \end{itemdescr} -\rSec3[sf.cmath.sph_legendre]{Spherical associated Legendre functions}% +\rSec3[sf.cmath.sph.legendre]{Spherical associated Legendre functions}% \indexlibrary{\idxcode{sph_legendre}}% \indexlibrary{\idxcode{sph_legendref}}% \indexlibrary{\idxcode{sph_legendrel}}% @@ -10207,10 +10195,10 @@ if \tcode{l >= 128}. \pnum -See also \ref{sf.cmath.assoc_legendre}. +See also \ref{sf.cmath.assoc.legendre}. \end{itemdescr} -\rSec3[sf.cmath.sph_neumann]{Spherical Neumann functions}% +\rSec3[sf.cmath.sph.neumann]{Spherical Neumann functions}% \indexlibrary{\idxcode{sph_neumann}}% \indexlibrary{\idxcode{sph_neumannf}}% \indexlibrary{\idxcode{sph_neumannl}}% @@ -10246,7 +10234,7 @@ if \tcode{n >= 128}. \pnum -See also \ref{sf.cmath.cyl_neumann}. +See also \ref{sf.cmath.cyl.neumann}. \end{itemdescr} \indextext{mathematical special functions|)} diff --git a/source/overloading.tex b/source/overloading.tex index 0602fc540a..6df045151e 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -845,7 +845,7 @@ form \begin{ncsimplebnf} -\terminal{operator} conversion-type-id \terminal{(\,)} cv-qualifier \opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \terminal{;} +\keyword{operator} conversion-type-id \terminal{(\,)} cv-qualifier \opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \terminal{;} \end{ncsimplebnf} where @@ -1072,18 +1072,14 @@ \end{itemize} \item -For the -relational\iref{expr.rel} and -equality\iref{expr.eq} operators, +For the relational\iref{expr.rel} operators, the rewritten candidates include all member, non-member, and built-in candidates for the operator \tcode{<=>} for which the rewritten expression \tcode{(x <=> y) @ 0} is well-formed using that \tcode{operator<=>}. For the -relational\iref{expr.rel}, -equality\iref{expr.eq}, -and +relational\iref{expr.rel} and three-way comparison\iref{expr.spaceship} operators, the rewritten candidates also include @@ -1093,6 +1089,18 @@ for the operator \tcode{<=>} for which the rewritten expression \tcode{0 @ (y <=> x)} is well-formed using that \tcode{operator<=>}. +For the \tcode{!=} operator\iref{expr.eq}, +the rewritten candidates +include all member, non-member, and built-in candidates +for the operator \tcode{==} +for which the rewritten expression \tcode{(x == y)} is well-formed +when contextually converted to \tcode{bool} using that operator \tcode{==}. +For the equality operators, +the rewritten candidates also include a synthesized candidate, +with the order of the two parameters reversed, +for each member, non-member, and built-in candidate for the operator \tcode{==} +for which the rewritten expression \tcode{(y == x)} is well-formed +when contextually converted to \tcode{bool} using that operator \tcode{==}. \begin{note} A candidate synthesized from a member candidate has its implicit object parameter as the second parameter, thus implicit conversions @@ -1151,8 +1159,8 @@ \end{example} \pnum -If a rewritten candidate -is selected by overload resolution for an operator \tcode{@}, +If a rewritten candidate is selected by overload resolution +for a relational or three-way comparison operator \tcode{@}, \tcode{x @ y} is interpreted as the rewritten expression: \tcode{0 @ (y <=> x)} @@ -1160,6 +1168,17 @@ with reversed order of parameters, or \tcode{(x <=> y) @ 0} otherwise, using the selected rewritten \tcode{operator<=>} candidate. +If a rewritten candidate is selected by overload resolution +for a \tcode{!=} operator, +\tcode{x != y} is interpreted as \tcode{(y == x) ?\ false :\ true} +if the selected candidate is a synthesized candidate +with reversed order of parameters, or +\tcode{(x == y) ?\ false :\ true} otherwise, +using the selected rewritten \tcode{operator==} candidate. +If a rewritten candidate is selected by overload resolution +for an \tcode{==} operator, +\tcode{x == y} is interpreted as \tcode{(y == x) ?\ true :\ false} +using the selected rewritten \tcode{operator==} candidate. \pnum If a built-in candidate is selected by overload resolution, the @@ -1406,9 +1425,11 @@ with ``\cvqual{cv2} \tcode{T2}'', are candidate functions. For direct-initialization, those explicit conversion functions that are not hidden within \tcode{S} and yield -type ``lvalue reference to \cvqual{cv2} \tcode{T2}'' or ``\cvqual{cv2} -\tcode{T2}'' or ``rvalue reference to \cvqual{cv2} \tcode{T2}'', -respectively, where \tcode{T2} is the same type as \tcode{T} or can be +type ``lvalue reference to \cvqual{cv2} \tcode{T2}'' +(when initializing an lvalue reference or an rvalue reference to function) +or ``rvalue reference to \cvqual{cv2} \tcode{T2}'' +(when initializing an rvalue reference or an lvalue reference to function), +where \tcode{T2} is the same type as \tcode{T} or can be converted to type \tcode{T} with a qualification conversion\iref{conv.qual}, are also candidate functions. @@ -1674,6 +1695,7 @@ another. \end{itemize} +\pnum Given these definitions, a viable function \tcode{F1} is defined @@ -1888,8 +1910,7 @@ was not better than \tcode{G}. Hence, -\tcode{W} -is either +either \tcode{W} is the best function or there is no best function. So, make a second pass over the viable @@ -2136,7 +2157,7 @@ \pnum \begin{note} As described in \ref{conv}, -a standard conversion sequence is either the Identity conversion +a standard conversion sequence either is the Identity conversion by itself (that is, no conversion) or consists of one to three conversions from the other four categories. @@ -3098,18 +3119,18 @@ \begin{bnf} \nontermdef{operator-function-id}\br - \terminal{operator} operator + \keyword{operator} operator \end{bnf} \begin{bnf} %% Ed. note: character protrusion would misalign various operators. \microtypesetup{protrusion=false}\obeyspaces \nontermdef{operator} \textnormal{one of}\br - \terminal{new delete new[] delete[] (\rlap{\,)} [\rlap{\,]} -> ->* \~}\br - \terminal{! + - * / \% \caret{} \& |}\br - \terminal{= += -= *= /= \%= \caret{}= \&= |=}\br - \terminal{== != < > <= >= <=> \&\& ||}\br - \terminal{<< >> <<= >>= ++ -- ,}\br + \terminal{new delete new[] delete[] co_await (\rlap{\,)} [\rlap{\,]} -> ->*}\br + \terminal{\~ ! + - * / \% \caret{} \&}\br + \terminal{| = += -= *= /= \%= \caret{}= \&=}\br + \terminal{|= == != < > <= >= <=> \&\&}\br + \terminal{|| << >> <<= >>= ++ -- ,}\br \end{bnf} \begin{note} The operators @@ -3174,6 +3195,12 @@ found in the rest of this subclause do not apply to them unless explicitly stated in~\ref{basic.stc.dynamic}. +\pnum +The \tcode{co_await} operator is described completely in~\ref{expr.await}. +The attributes and restrictions +found in the rest of this subclause do not apply to it unless explicitly +stated in~\ref{expr.await}. + \pnum \indextext{restriction!overloading}% An operator function @@ -3414,7 +3441,7 @@ uses \tcode{->}. \begin{ncsimplebnf} -postfix-expression \terminal{->} \terminal{\opt{template}} id-expression +postfix-expression \terminal{->} \opt{\keyword{template}} id-expression \end{ncsimplebnf} An expression @@ -3504,8 +3531,8 @@ \begin{bnf} \nontermdef{literal-operator-id}\br - \terminal{operator} string-literal identifier\br - \terminal{operator} user-defined-string-literal + \keyword{operator} string-literal identifier\br + \keyword{operator} user-defined-string-literal \end{bnf} \pnum @@ -3581,8 +3608,9 @@ the constraints described above, they are ordinary namespace-scope functions and function templates. In particular, they are looked up like ordinary functions and function templates and they follow the same overload resolution rules. Also, -they can be declared \tcode{inline} or \tcode{constexpr}, they may have internal -or external linkage, they can be called explicitly, their addresses can be +they can be declared \tcode{inline} or \tcode{constexpr}, +they may have internal, module, or external linkage, +they can be called explicitly, their addresses can be taken, etc. \end{note} \pnum diff --git a/source/preprocessor.tex b/source/preprocessor.tex index e43db6a9d7..8a523e862b 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -14,9 +14,9 @@ The first token in the sequence is a \tcode{\#} preprocessing token that (at the start of translation phase 4) -is either the first character in the source file +either is the first character in the source file (optionally after white space containing no new-line characters) -or that follows white space containing at least one new-line character. +or follows white space containing at least one new-line character. The last token in the sequence is the first new-line character that follows the first token in the sequence.\footnote{Thus, preprocessing directives are commonly called ``lines''. @@ -161,6 +161,7 @@ The implementation can process and skip sections of source files conditionally, include other source files, +import macros from header units, and replace macros. These capabilities are called \defn{preprocessing}, @@ -205,13 +206,17 @@ h-pp-tokens h-preprocessing-token \end{bnf} +\begin{bnf} +\nontermdef{header-name-tokens}\br + string-literal\br + \terminal{<} h-pp-tokens \terminal{>} +\end{bnf} + \indextext{\idxxname{has_include}}% \begin{bnf} \nontermdef{has-include-expression}\br - \terminal{\xname{has_include} ( <} h-char-sequence \terminal{> )}\br - \terminal{\xname{has_include} ( "} q-char-sequence \terminal{" )}\br - \terminal{\xname{has_include} (} string-literal \terminal{)}\br - \terminal{\xname{has_include} ( <} h-pp-tokens \terminal{> )} + \terminal{\xname{has_include}} \terminal{(} header-name \terminal{)}\br + \terminal{\xname{has_include}} \terminal{(} header-name-tokens \terminal{)} \end{bnf} \indextext{\idxxname{has_cpp_attribute}}% @@ -238,7 +243,9 @@ if the identifier is currently defined as a macro name (that is, if it is predefined -or if it has been the subject of a +or if it has one or more active macro definitions\iref{cpp.module}, +for example because +it has been the subject of a \tcode{\#define} preprocessing directive without an intervening @@ -246,8 +253,8 @@ directive with the same subject identifier), \tcode{0} if it is not. \pnum -The third and fourth forms of \grammarterm{has-include-expression} -are considered only if neither of the first or second forms matches, +The second form of \grammarterm{has-include-expression} +is considered only if the first form does not match, in which case the preprocessing tokens are processed just as in normal text. \pnum @@ -611,6 +618,15 @@ directive in another file, up to an \impldef{nesting limit for \tcode{\#include} directives} nesting limit. +\pnum +If the header identified by the \grammarterm{header-name} +denotes an importable header\iref{module.import}, +the preprocessing directive +is instead replaced by the \grammarterm{preprocessing-token}{s} +\begin{ncbnf} +\terminal{import} header-name \terminal{;} +\end{ncbnf} + \pnum \begin{note} Although an implementation may provide a mechanism for making arbitrary @@ -646,6 +662,188 @@ \end{codeblock} \end{example} +\rSec1[cpp.glob.frag]{Global module fragment} + +\begin{bnf} +\nontermdef{pp-global-module-fragment}\br + \terminal{module} \terminal{;} pp-balanced-token-seq \terminal{module} +\end{bnf} + +\pnum +If the first two preprocessing tokens at the start of phase 4 of translation +are \tcode{module} \tcode{;}, +the result of preprocessing shall begin with +a \grammarterm{pp-global-module-fragment} +for which all \grammarterm{preprocessing-token}{s} +in the \grammarterm{pp-balanced-token-seq} +were produced directly or indirectly by source file inclusion\iref{cpp.include}, +and for which the second \tcode{module} \grammarterm{preprocessing-token} +was not produced by source file inclusion or +macro replacement\iref{cpp.replace}. +Otherwise, +the first two preprocessing tokens at the end of phase 4 of translation +shall not be \tcode{module} \tcode{;}. + +\rSec1[cpp.module]{Header units} +\indextext{header unit!preprocessing}% +\indextext{macro import|(}% + +\begin{bnf} +\nontermdef{import-seq}\br + \opt{top-level-token-seq} \opt{\terminal{export}} \terminal{import} +\end{bnf} + +\begin{bnf} +\nontermdef{top-level-token-seq}\br + \descr{any \grammarterm{pp-balanced-token-seq} ending in \terminal{;} or \terminal{\}}} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-import}\br + \terminal{import} header-name \opt{pp-import-suffix} \terminal{;}\br + \terminal{import} header-name-tokens \opt{pp-import-suffix} \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-import-suffix}\br + pp-import-suffix-token\br + pp-import-suffix pp-import-suffix-token +\end{bnf} + +\begin{bnf} +\nontermdef{pp-import-suffix-token}\br + \descr{any \grammarterm{pp-balanced-token} other than \terminal{;}} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-balanced-token-seq}\br + pp-balanced-token\br + pp-balanced-token-seq pp-balanced-token +\end{bnf} + +\begin{bnf} +\nontermdef{pp-balanced-token}\br + pp-ldelim \opt{pp-balanced-token-seq} pp-rdelim\br + \descr{any \grammarterm{preprocessing-token} other than a \grammarterm{pp-ldelim} or \grammarterm{pp-rdelim}} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-ldelim} \descr{one of}\br + \terminal{( [ \{ <: <\%} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-rdelim} \descr{one of}\br + \terminal{) ] \} :> \%>} +\end{bnf} + +\pnum +A sequence of \grammarterm{preprocessing-token}{s} +matching the form of a \grammarterm{pp-import} +instructs the preprocessor to import macros +from the header unit\iref{module.import} +denoted by the \grammarterm{header-name}. +A \grammarterm{pp-import} is only recognized +when the sequence of tokens +produced by phase 4 of translation +up to the \tcode{import} token +forms an \grammarterm{import-seq}, +and the \tcode{import} token is not within +the \grammarterm{header-name-tokens} or \grammarterm{pp-import-suffix} +of another \grammarterm{pp-import}. +The \tcode{;} \grammarterm{preprocessing-token} +terminating a \grammarterm{pp-import} +shall not have been produced by +macro replacement\iref{cpp.replace}. +The \defnadj{point of}{macro import} for a \grammarterm{pp-import} is +immediately after the \tcode{;} terminating the \grammarterm{pp-import}. + +\pnum +In the second form of \grammarterm{pp-import}, +a \grammarterm{header-name} token is formed as if +the \grammarterm{header-name-tokens} +were the \grammarterm{pp-tokens} of a \tcode{\#include} directive. +The \grammarterm{header-name-tokens} are replaced by +the \grammarterm{header-name} token. +\begin{note} +This ensures that imports are treated consistently by +the preprocessor and later phases of translation. +\end{note} + +\pnum +Each \tcode{\#define} directive encountered when preprocessing +each translation unit in a program results in a distinct +\defn{macro definition}. +Importing macros from a header unit makes macro definitions +from a translation unit visible in other translation units. +Each macro definition has at most one point of definition in +each translation unit and at most one point of undefinition, as follows: +\begin{itemize} +\item +The \defnx{point of definition}{macro definition!point of definition} +of a macro definition within a translation unit +is the point at which its \tcode{\#define} directive occurs (in the translation +unit containing the \tcode{\#define} directive), or, +if the macro name is not lexically identical to a keyword\iref{lex.key} +or to the \grammarterm{identifier}{s} \tcode{module} or \tcode{import}, +the first point +of macro import of a translation unit containing a point of definition for the +macro definition, if any (in any other translation unit). + +\item +The \defnx{point of undefinition}{macro definition!point of undefinition} +of a macro definition within a translation unit +is the first point at which a \tcode{\#undef} directive naming the macro occurs +after its point of definition, or the first point +of macro import of a translation unit containing a point of undefinition for the +macro definition, whichever (if any) occurs first. +\end{itemize} + +\pnum +A macro directive is \defnx{active}{macro definition!active} at a source location +if it has a point of definition in that translation unit preceding the location, +and does not have a point of undefinition in that translation unit preceding +the location. + +\pnum +If a macro would be replaced or redefined, and multiple macro definitions +are active for that macro name, the active macro definitions shall all be +valid redefinitions of the same macro\iref{cpp.replace}. +\begin{note} +The relative order of \grammarterm{pp-import}{s} has no bearing on whether a +particular macro definition is active. +\end{note} + +\pnum +\begin{example} +\begin{codeblocktu}{Importable header \tcode{"a.h"}} +#define X 123 // \#1 +#define Y 45 // \#2 +#define Z a // \#3 +#undef X // point of undefinition of \#1 in \tcode{"a.h"} +\end{codeblocktu} + +\begin{codeblocktu}{Importable header \tcode{"b.h"}} +import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"b.h"} +#define X 456 // OK, \#1 is not active +#define Y 6 // error: \#2 is active +\end{codeblocktu} + +\begin{codeblocktu}{Importable header \tcode{"c.h"}} +#define Y 45 // \#4 +#define Z c // \#5 +\end{codeblocktu} + +\begin{codeblocktu}{Importable header \tcode{"d.h"}} +import "a.h"; // point of definition of \#1, \#2, and \#3, point of undefinition of \#1 in \tcode{"d.h"} +import "c.h"; // point of definition of \#4 and \#5 in \tcode{"d.h"} +int a = Y; // OK, active macro definitions \#2 and \#3 are valid redefinitions +int c = Z; // error: active macro definitions \#2 and \#3 are not valid redefinitions of \tcode{Z} +\end{codeblocktu} +\end{example} + +\indextext{macro import|)}% + \rSec1[cpp.replace]{Macro replacement}% \indextext{macro!replacement|(}% \indextext{replacement!macro|see{macro, replacement}}% @@ -1475,6 +1673,7 @@ \endhead \defnxname{cpp_aggregate_bases} & \tcode{201603L} \\ \rowsep \defnxname{cpp_aggregate_nsdmi} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_aggregate_paren_init} & \tcode{201902L} \\ \rowsep \defnxname{cpp_alias_templates} & \tcode{200704L} \\ \rowsep \defnxname{cpp_aligned_new} & \tcode{201606L} \\ \rowsep \defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep @@ -1483,6 +1682,7 @@ \defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep \defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep \defnxname{cpp_constexpr} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_coroutines} & \tcode{201902L} \\ \rowsep \defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep \defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep \defnxname{cpp_deduction_guides} & \tcode{201703L} \\ \rowsep @@ -1549,7 +1749,7 @@ 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 \tcode{wchar_t}, has the same value as the short identifier +stored in an object of type \tcode{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. diff --git a/source/ranges.tex b/source/ranges.tex index 6a1313fad0..8b94a6415c 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -53,9 +53,6 @@ template using sentinel_t = decltype(ranges::end(declval())); - template<@\placeholder{forwarding-range}@ R> - using safe_iterator_t = iterator_t; - template concept Range = @\seebelow@; @@ -112,8 +109,15 @@ requires (K == subrange_kind::sized || !SizedSentinel) class subrange; - template<@\placeholder{forwarding-range}@ R> - using safe_subrange_t = subrange>; + // \ref{range.dangling}, dangling iterator handling + struct dangling; + + template + using safe_iterator_t = conditional_t<@\placeholder{forwarding-range}@, iterator_t, dangling>; + + template + using safe_subrange_t = + conditional_t<@\placeholder{forwarding-range}@, subrange>, dangling>; // \ref{range.empty}, empty view template @@ -145,6 +149,10 @@ template using all_view = decltype(view::all(declval())); + template + requires is_object_v + class ref_view; + // \ref{range.filter}, filter view template> Pred> requires View && is_object_v @@ -180,7 +188,7 @@ template requires View && View && - IndirectlyComparable, iterator_t, ranges::equal_to<>> && + IndirectlyComparable, iterator_t, ranges::equal_to> && (ForwardRange || @\placeholder{tiny-range}@) class split_view; @@ -1253,6 +1261,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects \range{i}{s} is a valid range. + \pnum \effects Initializes \tcode{begin_} with \tcode{i} and \tcode{end_} with \tcode{s}. @@ -1266,7 +1277,8 @@ \begin{itemdescr} \pnum -\expects \tcode{n == ranges::distance(i, s)}. +\expects \range{i}{s} is a valid range, and +\tcode{n == ranges::distance(i, s)}. \pnum \effects Initializes \tcode{begin_} with \tcode{i} and \tcode{end_} with @@ -1436,6 +1448,48 @@ \end{codeblock} \end{itemdescr} +\rSec2[range.dangling]{Dangling iterator handling} + +\pnum +The tag type \tcode{dangling} is used together +with the template aliases \tcode{safe_iterator_t} and \tcode{safe_subrange_t} +to indicate that an algorithm +that typically returns an iterator into or subrange of a \tcode{Range} argument +does not return an iterator or subrange +which could potentially reference a range +whose lifetime has ended for a particular rvalue \tcode{Range} argument +which does not model \tcode{\placeholder{forwarding-range}}\iref{range.range}. +\begin{codeblock} +namespace std { + struct dangling { + constexpr dangling() noexcept = default; + template + constexpr dangling(Args&&...) noexcept { } + }; +} +\end{codeblock} + +\pnum +\begin{example} +\begin{codeblock} +vector f(); +auto result1 = ranges::find(f(), 42); // \#1 +static_assert(Same); +auto vec = f(); +auto result2 = ranges::find(vec, 42); // \#2 +static_assert(Same::iterator>); +auto result3 = ranges::find(subrange{vec}, 42); // \#3 +static_assert(Same::iterator>); +\end{codeblock} +The call to \tcode{ranges::find} at \#1 returns \tcode{dangling} +since \tcode{f()} is an rvalue \tcode{vector}; +the \tcode{vector} could potentially be destroyed +before a returned iterator is dereferenced. +However, the calls at \#2 and \#3 both return iterators +since the lvalue \tcode{vec} and specializations of \tcode{subrange} +model \tcode{\placeholder{forwarding-range}}. +\end{example} + \rSec1[range.factories]{Range factories} \pnum @@ -1642,7 +1696,9 @@ requires @\placeholdernc{weakly-equality-comparable-with}@ class iota_view : public view_interface> { private: + // \ref{range.iota.iterator}, class \tcode{iota_view::iterator} struct iterator; // \expos + // \ref{range.iota.sentinel}, class \tcode{iota_view::sentinel} struct sentinel; // \expos W value_ = W(); // \expos Bound bound_ = Bound(); // \expos @@ -2343,28 +2399,28 @@ \item \tcode{\placeholdernc{decay-copy}(E)} if the decayed type of \tcode{E} models \libconcept{View}. -\item Otherwise, \tcode{\placeholder{ref-view}\{E\}} if that -expression is well-formed, where \tcode{\placeholder{ref-view}} -is the exposition-only \libconcept{View} specified below. +\item Otherwise, \tcode{ref_view\{E\}} if that expression is well-formed. \item Otherwise, \tcode{subrange\{E\}}. \end{itemize} -\rSec3[range.view.ref]{\placeholder{ref-view}} +\rSec3[range.ref.view]{Class template \tcode{ref_view}} +\pnum +\tcode{ref_view} is a \tcode{View} of the elements of some other \tcode{Range}. \begin{codeblock} namespace std::ranges { template requires is_object_v - class @\placeholder{ref-view}@ : public view_interface<@\placeholder{ref-view}@> { + class ref_view : public view_interface> { private: R* r_ = nullptr; // \expos public: - constexpr @\placeholdernc{ref-view}@() noexcept = default; + constexpr ref_view() noexcept = default; - template<@\placeholder{not-same-as}@<@\placeholder{ref-view}@> T> + template<@\placeholder{not-same-as}@ T> requires @\seebelow@ - constexpr @\placeholder{ref-view}@(T&& t); + constexpr ref_view(T&& t); constexpr R& base() const { return *r_; } @@ -2381,20 +2437,22 @@ constexpr auto data() const requires ContiguousRange { return ranges::data(*r_); } - friend constexpr iterator_t begin(@\placeholder{ref-view}@ r) + friend constexpr iterator_t begin(ref_view r) { return r.begin(); } - friend constexpr sentinel_t end(@\placeholder{ref-view}@ r) + friend constexpr sentinel_t end(ref_view r) { return r.end(); } }; + template + ref_view(R&) -> ref_view; } \end{codeblock} -\indexlibrary{\idxcode{\placeholder{ref-view}}!\idxcode{\placeholder{ref-view}}}% +\indexlibrary{\idxcode{ref_view}}% \begin{itemdecl} -template<@\placeholder{not-same-as}@<@\placeholder{ref-view}@> T> +template<@\placeholder{not-same-as}@ T> requires @\seebelow@ -constexpr @\placeholder{ref-view}@(T&& t); +constexpr ref_view(T&& t); \end{itemdecl} \begin{itemdescr} @@ -2445,7 +2503,9 @@ V base_ = V(); // \expos @\placeholdernc{semiregular}@ pred_; // \expos + // \ref{range.filter.iterator}, class \tcode{filter_view::iterator} class iterator; // \expos + // \ref{range.filter.sentinel}, class \tcode{filter_view::sentinel} class sentinel; // \expos public: @@ -2881,7 +2941,9 @@ RegularInvocable>> class transform_view : public view_interface> { private: + // \ref{range.transform.iterator}, class template \tcode{transform_view::iterator} template struct iterator; // \expos + // \ref{range.transform.sentinel}, class template \tcode{transform_view::sentinel} template struct sentinel; // \expos V base_ = V(); // \expos @@ -3560,6 +3622,7 @@ private: V base_ = V(); // \expos iter_difference_t> count_ = 0; // \expos + // \ref{range.take.sentinel}, class template \tcode{take_view::sentinel} template struct sentinel; // \expos public: take_view() = default; @@ -3782,8 +3845,10 @@ private: using InnerRng = // \expos iter_reference_t>; + // \ref{range.join.iterator}, class template \tcode{join_view::iterator} template struct iterator; // \expos + // \ref{range.join.sentinel}, class template \tcode{join_view::sentinel} template struct sentinel; // \expos @@ -4302,14 +4367,16 @@ template requires View && View && - IndirectlyComparable, iterator_t, ranges::equal_to<>> && + IndirectlyComparable, iterator_t, ranges::equal_to> && (ForwardRange || @\placeholdernc{tiny-range}@) class split_view : public view_interface> { private: V base_ = V(); // \expos Pattern pattern_ = Pattern(); // \expos iterator_t current_ = iterator_t(); // \expos, present only if \tcode{!ForwardRange} + // \ref{range.split.outer}, class template \tcode{split_view::outer_iterator} template struct outer_iterator; // \expos + // \ref{range.split.inner}, class template \tcode{split_view::inner_iterator} template struct inner_iterator; // \expos public: split_view() = default; @@ -5107,5 +5174,32 @@ The name \tcode{view::reverse} denotes a range adaptor object\iref{range.adaptor.object}. For some subexpression \tcode{E}, the expression -\tcode{view::reverse(E)} is expression-equivalent to -\tcode{reverse_view\{E\}}. +\tcode{view::reverse(E)} is expression-equivalent to: +\begin{itemize} +\item + If the type of \tcode{E} is + a (possibly cv-qualified) specialization of \tcode{reverse_view}, + equivalent to \tcode{E.base()}. +\item + Otherwise, if the type of \tcode{E} is cv-qualified +\begin{codeblock} +subrange, reverse_iterator, K> +\end{codeblock} + for some iterator type \tcode{I} and + value \tcode{K} of type \tcode{subrange_kind}, + \begin{itemize} + \item + if \tcode{K} is \tcode{subrange_kind::sized}, equivalent to: +\begin{codeblock} +subrange(E.end().base(), E.begin().base(), E.size()) +\end{codeblock} + \item + otherwise, equivalent to: +\begin{codeblock} +subrange(E.end().base(), E.begin().base()) +\end{codeblock} + \end{itemize} + However, in either case \tcode{E} is evaluated only once. +\item + Otherwise, equivalent to \tcode{reverse_view\{E\}}. +\end{itemize} diff --git a/source/statements.tex b/source/statements.tex index 6a18726066..93bb5d4f9a 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -31,6 +31,43 @@ The optional \grammarterm{attribute-specifier-seq} appertains to the respective statement. +\pnum +A \defn{substatement} of a \grammarterm{statement} is one of the following: +\begin{itemize} +\item + for a \grammarterm{labeled-statement}, its contained \grammarterm{statement}, +\item + for a \grammarterm{compound-statement}, any \grammarterm{statement} of its \grammarterm{statement-seq}, +\item + for a \grammarterm{selection-statement}, any of its \grammarterm{statement}{s} (but not its \grammarterm{init-statement}), or +\item + for an \grammarterm{iteration-statement}, its contained \grammarterm{statement} (but not an \grammarterm{init-statement}). +\end{itemize} +\begin{note} +The \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +is not a substatement of the \grammarterm{statement} (if any) +in which the \grammarterm{lambda-expression} lexically appears. +\end{note} + +\pnum +A \grammarterm{statement} \tcode{S1} \defnx{encloses}{enclosing statement} +a \grammarterm{statement} \tcode{S2} if +\begin{itemize} +\item + \tcode{S2} is a substatement of \tcode{S1}\iref{dcl.dcl}, +\item + \tcode{S1} is a \grammarterm{selection-statement} or + \grammarterm{iteration-statement} and + \tcode{S2} is the \grammarterm{init-statement} of \tcode{S1}, +\item + \tcode{S1} is a \grammarterm{try-block} and \tcode{S2} + is its \grammarterm{compound-statement} or + any of the \grammarterm{compound-statement}{s} of + its \grammarterm{handler}{s}, or +\item + \tcode{S1} encloses a statement \tcode{S3} and \tcode{S3} encloses \tcode{S2}. +\end{itemize} + \pnum \indextext{\idxgram{condition}{s}!rules for}% The rules for \grammarterm{condition}{s} apply both to @@ -47,8 +84,8 @@ \pnum \indextext{statement!declaration in \tcode{if}}% \indextext{statement!declaration in \tcode{switch}}% -A name introduced by a declaration in a \grammarterm{condition} (either -introduced by the \grammarterm{decl-specifier-seq} or the +A name introduced by a declaration in a \grammarterm{condition} +(introduced by either the \grammarterm{decl-specifier-seq} or the \grammarterm{declarator} of the condition) is in scope from its point of declaration until the end of the substatements controlled by the condition. If the name is redeclared in the outermost block of a @@ -106,8 +143,8 @@ \begin{bnf} \nontermdef{labeled-statement}\br \opt{attribute-specifier-seq} identifier \terminal{:} statement\br - \opt{attribute-specifier-seq} \terminal{case} constant-expression \terminal{:} statement\br - \opt{attribute-specifier-seq} \terminal{default :} statement + \opt{attribute-specifier-seq} \keyword{case} constant-expression \terminal{:} statement\br + \opt{attribute-specifier-seq} \keyword{default} \terminal{:} statement \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the label. An @@ -199,25 +236,24 @@ % \begin{bnf} \nontermdef{selection-statement}\br - \terminal{if \opt{constexpr} (} \opt{init-statement} condition \terminal{)} statement\br - \terminal{if \opt{constexpr} (} \opt{init-statement} condition \terminal{)} statement \terminal{else} statement\br - \terminal{switch (} \opt{init-statement} condition \terminal{)} statement + \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement\br + \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement \keyword{else} statement\br + \keyword{switch} \terminal{(} \opt{init-statement} condition \terminal{)} statement \end{bnf} See~\ref{dcl.meaning} for the optional \grammarterm{attribute-specifier-seq} in a condition. \begin{note} An \grammarterm{init-statement} ends with a semicolon. \end{note} -In \ref{stmt.stmt}, the term \term{substatement} refers to -the contained \grammarterm{statement} or \grammarterm{statement}{s} that appear -in the syntax notation. + +\pnum \indextext{scope!\idxgram{selection-statement}}% The substatement in a \grammarterm{selection-statement} (each substatement, in the \tcode{else} form of the \tcode{if} statement) implicitly defines a block scope\iref{basic.scope}. If the substatement in a -selection-statement is a single statement and not a +\grammarterm{selection-statement} is a single statement and not a \grammarterm{compound-statement}, it is as if it was rewritten to be a -compound-statement containing the original substatement. +\grammarterm{compound-statement} containing the original substatement. \begin{example} \begin{codeblock} @@ -297,24 +333,24 @@ \pnum An \tcode{if} statement of the form \begin{ncsimplebnf} -\terminal{if \opt{constexpr} (} init-statement condition \terminal{)} statement +\keyword{if} \opt{\keyword{constexpr}} \terminal{(} init-statement condition \terminal{)} statement \end{ncsimplebnf} is equivalent to \begin{ncsimplebnf} \terminal{\{}\br \bnfindent init-statement\br -\bnfindent \terminal{if \opt{constexpr} (} condition \terminal{)} statement\br +\bnfindent \keyword{if} \opt{\keyword{constexpr}} \terminal{(} condition \terminal{)} statement\br \terminal{\}} \end{ncsimplebnf} and an \tcode{if} statement of the form \begin{ncsimplebnf} -\terminal{if \opt{constexpr} (} init-statement condition \terminal{)} statement \terminal{else} statement +\keyword{if} \opt{\keyword{constexpr}} \terminal{(} init-statement condition \terminal{)} statement \keyword{else} statement \end{ncsimplebnf} is equivalent to \begin{ncsimplebnf} \terminal{\{}\br \bnfindent init-statement\br -\bnfindent \terminal{if \opt{constexpr} (} condition \terminal{)} statement \terminal{else} statement\br +\bnfindent \keyword{if} \opt{\keyword{constexpr}} \terminal{(} condition \terminal{)} statement \keyword{else} statement\br \terminal{\}} \end{ncsimplebnf} except that names declared in the \grammarterm{init-statement} are in @@ -342,7 +378,7 @@ \begin{ncbnf} \indextext{label!\idxcode{case}}% -\terminal{case} constant-expression \terminal{:} +\keyword{case} constant-expression \terminal{:} \end{ncbnf} where the \grammarterm{constant-expression} shall be @@ -393,13 +429,13 @@ \pnum A \tcode{switch} statement of the form \begin{ncsimplebnf} -\terminal{switch (} init-statement condition \terminal{)} statement +\keyword{switch} \terminal{(} init-statement condition \terminal{)} statement \end{ncsimplebnf} is equivalent to \begin{ncsimplebnf} \terminal{\{}\br \bnfindent init-statement\br -\bnfindent \terminal{switch (} condition \terminal{)} statement\br +\bnfindent \keyword{switch} \terminal{(} condition \terminal{)} statement\br \terminal{\}} \end{ncsimplebnf} except that names declared in the \grammarterm{init-statement} are in @@ -419,10 +455,10 @@ % \begin{bnf} \nontermdef{iteration-statement}\br - \terminal{while (} condition \terminal{)} statement\br - \terminal{do} statement \terminal{while (} expression \terminal{) ;}\br - \terminal{for (} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement\br - \terminal{for (} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement + \keyword{while} \terminal{(} condition \terminal{)} statement\br + \keyword{do} statement \keyword{while} \terminal{(} expression \terminal{) ;}\br + \keyword{for} \terminal{(} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement\br + \keyword{for} \terminal{(} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement \end{bnf} \begin{bnf} @@ -443,14 +479,14 @@ \end{note} \pnum +\indextext{scope!\idxgram{iteration-statement}}% The substatement in an \grammarterm{iteration-statement} implicitly defines a block scope\iref{basic.scope} which is entered and exited each time through the loop. - -\indextext{scope!\idxgram{iteration-statement}}% -If the substatement in an iteration-statement is a single statement and -not a \grammarterm{compound-statement}, it is as if it was rewritten to be -a compound-statement containing the original statement. +If the substatement in an \grammarterm{iteration-statement} is +a single statement and not a \grammarterm{compound-statement}, +it is as if it was rewritten to be +a \grammarterm{compound-statement} containing the original statement. \begin{example} \begin{codeblock} @@ -500,11 +536,11 @@ declaration\iref{basic.scope.pdecl} to the end of the \tcode{while} \grammarterm{statement}. A \tcode{while} statement is equivalent to \begin{ncsimplebnf} -\terminal{label:}\br +\exposid{label} \terminal{:}\br \terminal{\{}\br -\bnfindent \terminal{if (} condition \terminal{) \{}\br +\bnfindent \keyword{if} \terminal{(} condition \terminal{) \{}\br \bnfindent \bnfindent statement\br -\bnfindent \bnfindent \terminal{goto label;}\br +\bnfindent \bnfindent \keyword{goto} \exposid{label} \terminal{;}\br \bnfindent \terminal{\}}\br \terminal{\}} \end{ncsimplebnf} @@ -549,13 +585,13 @@ \pnum The \tcode{for} statement \begin{ncsimplebnf} -\terminal{for (} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement +\keyword{for} \terminal{(} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement \end{ncsimplebnf} is equivalent to \begin{ncsimplebnf} \terminal{\{}\br \bnfindent init-statement\br -\bnfindent \terminal{while (} condition \terminal{) \{}\br +\bnfindent \keyword{while} \terminal{(} condition \terminal{) \{}\br \bnfindent\bnfindent statement\br \bnfindent\bnfindent expression \terminal{;}\br \bnfindent \terminal{\}}\br @@ -607,17 +643,17 @@ \pnum The range-based \tcode{for} statement \begin{ncsimplebnf} -\terminal{for (} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement +\keyword{for} \terminal{(} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement \end{ncsimplebnf} is equivalent to \begin{ncsimplebnf} \terminal{\{}\br \bnfindent \opt{init-statement}\br -\bnfindent \terminal{auto \&\&__range =} for-range-initializer \terminal{;}\br -\bnfindent \terminal{auto __begin =} begin-expr \terminal{;}\br -\bnfindent \terminal{auto __end =} end-expr \terminal{;}\br -\bnfindent \terminal{for ( ; __begin != __end; ++__begin ) \{}\br -\bnfindent\bnfindent for-range-declaration \terminal{= *__begin;}\br +\bnfindent \keyword{auto} \terminal{\&\&}\exposid{range} \terminal{=} for-range-initializer \terminal{;}\br +\bnfindent \keyword{auto} \exposid{begin} \terminal{=} begin-expr \terminal{;}\br +\bnfindent \keyword{auto} \exposid{end} \terminal{=} end-expr \terminal{;}\br +\bnfindent \keyword{for} \terminal{( ;} \exposid{begin} \terminal{!=} \exposid{end}\terminal{; ++}\exposid{begin} \terminal{) \{}\br +\bnfindent\bnfindent for-range-declaration \terminal{= *} \exposid{begin} \terminal{;}\br \bnfindent\bnfindent statement\br \bnfindent \terminal{\}}\br \terminal{\}} @@ -629,7 +665,7 @@ it is regarded as if it were surrounded by parentheses (so that a comma operator cannot be reinterpreted as delimiting two \grammarterm{init-declarator}{s}); -\item \tcode{__range}, \tcode{__begin}, and \tcode{__end} are variables defined for +\item \exposid{range}, \exposid{begin}, and \exposid{end} are variables defined for exposition only; and \item @@ -638,7 +674,8 @@ \begin{itemize} \item if the \grammarterm{for-range-initializer} is an expression of array type \tcode{R}, \placeholder{begin-expr} and \placeholder{end-expr} are -\tcode{__range} and \tcode{__range + __bound}, respectively, where \tcode{__bound} is +\exposid{range} and \exposid{range} \tcode{+} \tcode{N}, respectively, +where \tcode{N} is the array bound. If \tcode{R} is an array of unknown bound or an array of incomplete type, the program is ill-formed; @@ -647,11 +684,12 @@ \tcode{begin} and \tcode{end} are looked up in the scope of \tcode{C} as if by class member access lookup\iref{basic.lookup.classref}, and if both find at least one declaration, \placeholder{begin-expr} and -\placeholder{end-expr} are \tcode{__range.begin()} and \tcode{__range.end()}, +\placeholder{end-expr} are \tcode{\exposid{range}.begin()} and \tcode{\exposid{range}.end()}, respectively; -\item otherwise, \placeholder{begin-expr} and \placeholder{end-expr} are \tcode{begin(__range)} -and \tcode{end(__range)}, respectively, where \tcode{begin} and \tcode{end} are looked +\item otherwise, \placeholder{begin-expr} and \placeholder{end-expr} are +\tcode{begin(\exposid{range})} and \tcode{end(\exposid{range})}, respectively, +where \tcode{begin} and \tcode{end} are looked up in the associated namespaces\iref{basic.lookup.argdep}. \begin{note} Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. \end{note} @@ -688,10 +726,11 @@ % \begin{bnf} \nontermdef{jump-statement}\br - \terminal{break ;}\br - \terminal{continue ;}\br - \terminal{return} \opt{expr-or-braced-init-list} \terminal{;}\br - \terminal{goto} identifier \terminal{;} + \keyword{break ;}\br + \keyword{continue ;}\br + \keyword{return} \opt{expr-or-braced-init-list} \terminal{;}\br + coroutine-return-statement\br + \keyword{goto} identifier \terminal{;} \end{bnf} \pnum @@ -714,7 +753,10 @@ \indextext{\idxcode{abort}}% \indexlibrary{\idxcode{abort}}% \tcode{std::abort()}\iref{support.start.term}, for example) without -destroying class objects with automatic storage duration. +destroying objects with automatic storage duration. +\end{note} +\begin{note} +A suspension of a coroutine\iref{expr.await} is not considered to be an exit from a scope. \end{note} \rSec2[stmt.break]{The \tcode{break} statement}% @@ -748,7 +790,7 @@ { // ... } -contin: ; +@\exposid{contin}@: ; } \end{codeblock} \end{minipage} @@ -758,7 +800,7 @@ { // ... } -contin: ; +@\exposid{contin}@: ; } while (foo); \end{codeblock} \end{minipage} @@ -768,13 +810,13 @@ { // ... } -contin: ; +@\exposid{contin}@: ; } \end{codeblock} \end{minipage} a \tcode{continue} not contained in an enclosed iteration statement is -equivalent to \tcode{goto} \tcode{contin}. +equivalent to \tcode{goto} \exposid{contin}. \rSec2[stmt.return]{The \tcode{return} statement}% \indextext{\idxcode{return}}% @@ -816,10 +858,10 @@ Flowing off the end of a constructor, a destructor, or -a function with a \cv{}~\tcode{void} return type is +a non-coroutine function with a \cv{}~\tcode{void} return type is equivalent to a \tcode{return} with no operand. Otherwise, flowing off the end of a function -other than \tcode{main}\iref{basic.start.main} +other than \tcode{main}\iref{basic.start.main} or a coroutine\iref{dcl.fct.def.coroutine} results in undefined behavior. \pnum @@ -829,6 +871,51 @@ before the destruction of local variables\iref{stmt.jump} of the block enclosing the \tcode{return} statement. +\rSec3[stmt.return.coroutine]{The \tcode{co_return} statement}% +\indextext{\idxcode{co_return}}% +\indextext{coroutine return|see{\tcode{co_return}}}% + +\begin{bnf} +\nontermdef{coroutine-return-statement}\br + \terminal{co_return} \opt{expr-or-braced-init-list} \terminal{;} +\end{bnf} + +\pnum +A coroutine returns to its caller or resumer\iref{dcl.fct.def.coroutine} +by the \tcode{co_return} statement or when suspended\iref{expr.await}. +A coroutine shall not return to its caller or resumer +by a \tcode{return} statement\iref{stmt.return}. + +\pnum +The \grammarterm{expr-or-braced-init-list} of a \tcode{co_return} statement is +called its operand. +Let \placeholder{p} be an lvalue naming the coroutine +promise object\iref{dcl.fct.def.coroutine}. +A \tcode{co_return} statement is equivalent to: +\begin{ncsimplebnf} +\terminal{\{} S\terminal{; goto} \exposid{final-suspend}\terminal{;} \terminal{\}} +\end{ncsimplebnf} + +where \exposid{final-suspend} is the exposition-only label +defined in \ref{dcl.fct.def.coroutine} +and \placeholder{S} is defined as follows: + +\begin{itemize} +\item +\placeholder{S} is \placeholder{p}\tcode{.return_value(}\grammarterm{expr-or-braced-init-list}{}\tcode{)}, +if the operand is a \grammarterm{braced-init-list} or an expression of non-\tcode{void} type; + +\item +\placeholder{S} is \tcode{\{}{ }\opt{\grammarterm{expression}} \tcode{;} \placeholder{p}\tcode{.return_void()}\tcode{;{ }\}}, otherwise; +\end{itemize} + +\placeholder{S} shall be a prvalue of type \tcode{void}. + +\pnum +If \placeholder{p}\tcode{.return_void()} is a valid expression, +flowing off the end of a coroutine is equivalent to a \tcode{co_return} with no operand; +otherwise flowing off the end of a coroutine results in undefined behavior. + \rSec2[stmt.goto]{The \tcode{goto} statement}% \indextext{statement!\idxcode{goto}} @@ -876,9 +963,10 @@ A program that jumps\footnote{The transfer from the condition of a \tcode{switch} statement to a \tcode{case} label is considered a jump in this respect.} from a point where a variable with automatic storage duration is -not in scope to a point where it is in scope is ill-formed unless the -variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an -\grammarterm{initializer}\iref{dcl.init}. +not in scope to a point where it is in scope is ill-formed unless +the variable has vacuous initialization\iref{dcl.init}. +In such a case, the variables with vacuous initialization +are constructed in the order of their declaration. \begin{example} \begin{codeblock} @@ -929,8 +1017,8 @@ \pnum \indextext{\idxcode{static}!destruction of local}% -The destructor for a block-scope object with static or thread storage duration will be -executed if and only if it was constructed. +A block-scope object with static or thread storage duration will be +destroyed if and only if it was constructed. \begin{note} \ref{basic.start.term} describes the order in which block-scope objects with static and thread storage duration are destroyed. diff --git a/source/std.tex b/source/std.tex index a87c75c129..1d9c01fb5a 100644 --- a/source/std.tex +++ b/source/std.tex @@ -106,6 +106,7 @@ \include{expressions} \include{statements} \include{declarations} +\include{modules} \include{classes} \include{overloading} \include{templates} diff --git a/source/strings.tex b/source/strings.tex index 364a553219..eef5db0a36 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -224,9 +224,8 @@ \begin{itemdescr} \pnum -\requires -\tcode{state_type} -shall meet the +\expects +\tcode{state_type} meets the \oldconcept{Destructible} (\tref{destructible}), \oldconcept{CopyAssignable} (\tref{copyassignable}), \oldconcept{CopyConstructible} (\tref{copyconstructible}), and @@ -314,7 +313,7 @@ returns \tcode{EOF}. -\rSec3[char.traits.specializations.char8_t]{\tcode{struct char_traits}} +\rSec3[char.traits.specializations.char8.t]{\tcode{struct char_traits}} \indexlibrary{\idxcode{char_traits}}% \begin{codeblock} @@ -355,7 +354,7 @@ The member \tcode{eof()} returns an implementation-defined constant that cannot appear as a valid UTF-8 code unit. -\rSec3[char.traits.specializations.char16_t]{\tcode{struct char_traits}} +\rSec3[char.traits.specializations.char16.t]{\tcode{struct char_traits}} \indexlibrary{\idxcode{char_traits}}% \begin{codeblock} @@ -400,7 +399,7 @@ \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a valid UTF-16 code unit. -\rSec3[char.traits.specializations.char32_t]{\tcode{struct char_traits}} +\rSec3[char.traits.specializations.char32.t]{\tcode{struct char_traits}} \indexlibrary{\idxcode{char_traits}}% \begin{codeblock} @@ -1653,12 +1652,14 @@ by causing reallocation. \pnum -\complexity Linear in the size of the sequence. +\complexity If the size is not equal to the old capacity, +linear in the size of the sequence; +otherwise constant. \pnum \remarks Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence as well as the past-the-end iterator. -If no reallocation happens, they remain valid. +referring to the elements in the sequence, as well as the past-the-end iterator. +\begin{note} If no reallocation happens, they remain valid. \end{note} \end{itemdescr} \indexlibrarymember{clear}{basic_string}% @@ -2274,6 +2275,16 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\effects +Inserts \tcode{n} copies of \tcode{c} before the character at position \tcode{pos} +if \tcode{pos < size()}, +or otherwise at the end of the string. + +\pnum +\returns +\tcode{*this} + \pnum \throws \begin{itemize} @@ -2281,11 +2292,6 @@ \item \tcode{length_error} if \tcode{n > max_size() - size()}, or \item any exceptions thrown by \tcode{allocator_traits::allocate}. \end{itemize} -\pnum -\effects -Inserts \tcode{n} copies of \tcode{c} before the character at position \tcode{pos} -if \tcode{pos < size()}, -or otherwise at the end of the string. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% @@ -3559,7 +3565,7 @@ \indexlibrary{\idxcode{erase}!\idxcode{basic_string}}% \begin{itemdecl} -template +template void erase(basic_string& c, const U& value); \end{itemdecl} @@ -3571,7 +3577,7 @@ \indexlibrary{\idxcode{erase_if}!\idxcode{basic_string}}% \begin{itemdecl} -template +template void erase_if(basic_string& c, Predicate pred); \end{itemdecl} @@ -4090,10 +4096,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an empty \tcode{basic_string_view}. - \pnum \ensures \tcode{size_ == 0} and \tcode{data_ == nullptr}. @@ -4539,7 +4541,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return compare(0, npos, x) == 0;} +Equivalent to: \tcode{return substr(0, x.size()) == x;} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% @@ -4550,7 +4552,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return starts_with(basic_string_view(addressof(x), 1));} +Equivalent to: \tcode{return !empty() \&\& traits::eq(front(), x);} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% @@ -4586,7 +4588,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return ends_with(basic_string_view(addressof(x), 1));} +Equivalent to: \tcode{return !empty() \&\& traits::eq(back(), x);} \end{itemdescr} \indexlibrarymember{ends_with}{basic_string_view}% @@ -5533,7 +5535,7 @@ the multibyte character that corresponds to the U+0000 Unicode character (which is the value stored). -\item between \tcode{1} and \tcode{n} inclusive, +\item between \tcode{1} and \tcode{n} (inclusive), if the next n or fewer bytes complete a valid multibyte character (which is the value stored); the value returned is the number of bytes that complete the multibyte character. diff --git a/source/support.tex b/source/support.tex index 00f6e5aa08..c4e9903869 100644 --- a/source/support.tex +++ b/source/support.tex @@ -37,6 +37,7 @@ \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{cmp} & Comparisons & \tcode{} \\ \rowsep +\ref{support.coroutine} & Coroutines & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ & & \tcode{} \\ & & \tcode{} \\ @@ -349,11 +350,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum \constraints \tcode{is_integral_v} is \tcode{true}. + \pnum \effects Equivalent to: \tcode{return b = b << shift;} - -\pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_integral_v} is \tcode{true}. \end{itemdescr} \indexlibrarymember{operator<<}{byte}% @@ -363,14 +363,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum \constraints \tcode{is_integral_v} is \tcode{true}. + \pnum \effects Equivalent to: \begin{codeblock} return static_cast(static_cast( static_cast(b) << shift)); \end{codeblock} - -\pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_integral_v} is \tcode{true}. \end{itemdescr} \indexlibrarymember{operator>>=}{byte}% @@ -380,11 +379,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum \constraints \tcode{is_integral_v} is \tcode{true}. + \pnum \effects Equivalent to: \tcode{return b >> shift;} - -\pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_integral_v} is \tcode{true}. \end{itemdescr} \indexlibrarymember{operator>>}{byte}% @@ -394,14 +392,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum \constraints \tcode{is_integral_v} is \tcode{true}. + \pnum \effects Equivalent to: \begin{codeblock} return static_cast(static_cast( static_cast(b) >> shift)); \end{codeblock} - -\pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_integral_v} is \tcode{true}. \end{itemdescr} \indexlibrarymember{operator"|=}{byte}% @@ -490,10 +487,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum \effects Equivalent to: \tcode{return static_cast(b);} +\pnum \constraints \tcode{is_integral_v} is \tcode{true}. -\pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_integral_v} is \tcode{true}. +\pnum \effects Equivalent to: \tcode{return static_cast(b);} \end{itemdescr} \rSec1[support.limits]{Implementation properties} @@ -559,6 +555,8 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_bool_constant} & \tcode{201505L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_bounded_array_traits} & \tcode{201902L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_boyer_moore_searcher} & \tcode{201603L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_byte} & \tcode{201603L} & @@ -592,7 +590,7 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_exchange_function} & \tcode{201304L} & \tcode{} \\ \rowsep -\defnlibxname{cpp_lib_execution} & \tcode{201603L} & +\defnlibxname{cpp_lib_execution} & \tcode{201902L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_filesystem} & \tcode{201703L} & \tcode{} \\ \rowsep @@ -602,6 +600,8 @@ \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_generic_unordered_lookup} & \tcode{201811L} & \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_generic_unordered_hash_lookup} & \tcode{201902L} & + \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_hardware_interference_size} & \tcode{201703L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_has_unique_object_representations} & \tcode{201606L} & @@ -614,6 +614,8 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_integral_constant_callable} & \tcode{201304L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_interpolate} & \tcode{201902L} & + \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_invoke} & \tcode{201411L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_is_aggregate} & \tcode{201703L} & @@ -2250,9 +2252,9 @@ \end{note} \pnum -\requires -\tcode{ptr} shall be a null pointer or -its value shall represent the address of +\expects +\tcode{ptr} is a null pointer or +its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) \tcode{operator new(std::size_t)} @@ -2262,20 +2264,20 @@ \tcode{operator delete}. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum -\requires +\expects If the \tcode{alignment} parameter is not present, -\tcode{ptr} shall have been returned by an allocation function +\tcode{ptr} was returned by an allocation function without an \tcode{alignment} parameter. If present, the \tcode{alignment} argument -shall equal the \tcode{alignment} argument +is equal to the \tcode{alignment} argument passed to the allocation function that returned \tcode{ptr}. If present, the \tcode{size} argument -shall equal the \tcode{size} argument +is equal to the \tcode{size} argument passed to the allocation function that returned \tcode{ptr}. \pnum @@ -2340,9 +2342,9 @@ \replaceabledesc{either} \pnum -\requires -\tcode{ptr} shall be a null pointer or -its value shall represent the address of +\expects +\tcode{ptr} is a null pointer or +its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) \tcode{operator new(std::size_t)} @@ -2352,17 +2354,17 @@ \tcode{operator delete}. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum -\requires +\expects If the \tcode{alignment} parameter is not present, -\tcode{ptr} shall have been returned by an allocation function +\tcode{ptr} was returned by an allocation function without an \tcode{alignment} parameter. If present, the \tcode{alignment} argument -shall equal the \tcode{alignment} argument +is equal to the \tcode{alignment} argument passed to the allocation function that returned \tcode{ptr}. \pnum @@ -2505,9 +2507,9 @@ \end{note} \pnum -\requires -\tcode{ptr} shall be a null pointer or -its value shall represent the address of +\expects +\tcode{ptr} is a null pointer or +its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) \tcode{operator new[](std::size_t)} @@ -2517,20 +2519,20 @@ \tcode{operator delete[]}. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum -\requires +\expects If the \tcode{alignment} parameter is not present, -\tcode{ptr} shall have been returned by an allocation function +\tcode{ptr} was returned by an allocation function without an \tcode{alignment} parameter. If present, the \tcode{alignment} argument -shall equal the \tcode{alignment} argument +is equal to the \tcode{alignment} argument passed to the allocation function that returned \tcode{ptr}. If present, the \tcode{size} argument -shall equal the \tcode{size} argument +is equal to the \tcode{size} argument passed to the allocation function that returned \tcode{ptr}. \pnum @@ -2576,9 +2578,9 @@ \replaceabledesc{either} \pnum -\requires -\tcode{ptr} shall be a null pointer or -its value shall represent the address of +\expects +\tcode{ptr} is a null pointer or +its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) \tcode{operator new[](std::size_t)} @@ -2588,17 +2590,17 @@ \tcode{operator delete[]}. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum -\requires +\expects If the \tcode{alignment} parameter is not present, -\tcode{ptr} shall have been returned by an allocation function +\tcode{ptr} was returned by an allocation function without an \tcode{alignment} parameter. If present, the \tcode{alignment} argument -shall equal the \tcode{alignment} argument +is equal to the \tcode{alignment} argument passed to the allocation function that returned \tcode{ptr}. \pnum @@ -2667,9 +2669,9 @@ Intentionally performs no action. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum \remarks @@ -2690,9 +2692,9 @@ Intentionally performs no action. \pnum -\requires +\expects If an implementation has strict pointer safety\iref{basic.stc.dynamic.safety} -then \tcode{ptr} shall be a safely-derived pointer. +then \tcode{ptr} is a safely-derived pointer. \pnum \remarks @@ -2724,6 +2726,7 @@ \indexlibrary{\idxcode{bad_alloc}}% \rSec3[bad.alloc]{Class \tcode{bad_alloc}} +\indexlibrary{\idxcode{bad_alloc}!constructor}% \begin{codeblock} namespace std { class bad_alloc : public exception { @@ -2742,32 +2745,6 @@ defines the type of objects thrown as exceptions by the implementation to report a failure to allocate storage. -\indexlibrary{\idxcode{bad_alloc}!constructor}% -\begin{itemdecl} -bad_alloc() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{bad_alloc}. -\end{itemdescr} - -\indexlibrary{\idxcode{bad_alloc}!constructor}% -\indexlibrarymember{operator=}{bad_alloc}% -\begin{itemdecl} -bad_alloc(const bad_alloc&) noexcept; -bad_alloc& operator=(const bad_alloc&) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Copies an object of class -\tcode{bad_alloc}. -\end{itemdescr} - \indexlibrarymember{what}{bad_alloc}% \begin{itemdecl} const char* what() const noexcept override; @@ -2786,6 +2763,7 @@ \end{itemdescr} \indexlibrary{\idxcode{bad_array_new_length}}% +\indexlibrary{\idxcode{bad_array_new_length}!constructor}% \rSec3[new.badlength]{Class \tcode{bad_array_new_length}} \begin{codeblock} @@ -2804,16 +2782,6 @@ less than zero or greater than an \impldef{maximum size of an allocated object} limit\iref{expr.new}. -\indexlibrary{\idxcode{bad_array_new_length}!constructor}% -\begin{itemdecl} -bad_array_new_length() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{bad_array_new_length}. -\end{itemdescr} - \indexlibrarymember{what}{bad_array_new_length}% \begin{itemdecl} const char* what() const noexcept override; @@ -2911,7 +2879,11 @@ \begin{itemdescr} \pnum -\requires +\mandates +\tcode{!is_function_v \&\& !is_void_v} is \tcode{true}. + +\pnum +\expects \tcode{p} represents the address \placeholder{A} of a byte in memory. An object \placeholder{X} that is within its lifetime\iref{basic.life} and whose type is similar\iref{conv.qual} to \tcode{T} @@ -2936,8 +2908,6 @@ \placeholder{Y}, an object that is pointer-interconvertible with \placeholder{Y}, or the immediately-enclosing array object if \placeholder{Y} is an array element. -The program is ill-formed if \tcode{T} is a function type -or \cv{}~\tcode{void}. \pnum \begin{note} @@ -3149,6 +3119,7 @@ \rSec2[bad.cast]{Class \tcode{bad_cast}} \indexlibrary{\idxcode{bad_cast}}% +\indexlibrary{\idxcode{bad_cast}!constructor}% \begin{codeblock} namespace std { class bad_cast : public exception { @@ -3170,32 +3141,6 @@ \tcode{dynamic_cast} expression\iref{expr.dynamic.cast}. -\indexlibrary{\idxcode{bad_cast}!constructor}% -\begin{itemdecl} -bad_cast() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{bad_cast}. -\end{itemdescr} - -\indexlibrary{\idxcode{bad_cast}!constructor}% -\indexlibrarymember{operator=}{bad_cast}% -\begin{itemdecl} -bad_cast(const bad_cast&) noexcept; -bad_cast& operator=(const bad_cast&) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Copies an object of class -\tcode{bad_cast}. -\end{itemdescr} - \indexlibrarymember{what}{bad_cast}% \begin{itemdecl} const char* what() const noexcept override; @@ -3216,6 +3161,7 @@ \rSec2[bad.typeid]{Class \tcode{bad_typeid}} \indexlibrary{\idxcode{bad_typeid}}% +\indexlibrary{\idxcode{bad_typeid}!constructor}% \begin{codeblock} namespace std { class bad_typeid : public exception { @@ -3237,32 +3183,6 @@ \tcode{typeid} expression\iref{expr.typeid}. -\indexlibrary{\idxcode{bad_typeid}!constructor}% -\begin{itemdecl} -bad_typeid() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{bad_typeid}. -\end{itemdescr} - -\indexlibrary{\idxcode{bad_typeid}!constructor}% -\indexlibrarymember{operator=}{bad_typeid}% -\begin{itemdecl} -bad_typeid(const bad_typeid&) noexcept; -bad_typeid& operator=(const bad_typeid&) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Copies an object of class -\tcode{bad_typeid}. -\end{itemdescr} - \indexlibrarymember{what}{bad_typeid}% \begin{itemdecl} const char* what() const noexcept override; @@ -3410,6 +3330,7 @@ \rSec2[exception]{Class \tcode{exception}} \indexlibrary{\idxcode{exception}}% +\indexlibrary{\idxcode{exception}!constructor}% \begin{codeblock} namespace std { class exception { @@ -3439,18 +3360,6 @@ dynamic type \tcode{T} and \tcode{lhs} is a copy of \tcode{rhs}, then \tcode{strcmp(lhs.what(), rhs.what())} shall equal 0. -\indexlibrary{\idxcode{exception}!constructor}% -\begin{itemdecl} -exception() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{exception}. -\end{itemdescr} - \indexlibrary{\idxcode{exception}!constructor}% \indexlibrarymember{operator=}{exception}% \begin{itemdecl} @@ -3459,12 +3368,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Copies an -\tcode{exception} -object. - \pnum \ensures If \tcode{*this} and \tcode{rhs} both have dynamic type \tcode{exception} then the value of the expression \tcode{strcmp(what(), rhs.what())} shall equal 0. @@ -3505,6 +3408,7 @@ \rSec2[bad.exception]{Class \tcode{bad_exception}} \indexlibrary{\idxcode{bad_exception}}% +\indexlibrary{\idxcode{bad_exception}!constructor}% \begin{codeblock} namespace std { class bad_exception : public exception { @@ -3525,32 +3429,6 @@ returned from a call to \tcode{current_exception}\iref{propagation} when the currently active exception object fails to copy. -\indexlibrary{\idxcode{bad_exception}!constructor}% -\begin{itemdecl} -bad_exception() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of class -\tcode{bad_exception}. -\end{itemdescr} - -\indexlibrary{\idxcode{bad_exception}!constructor}% -\indexlibrarymember{operator=}{bad_exception}% -\begin{itemdecl} -bad_exception(const bad_exception&) noexcept; -bad_exception& operator=(const bad_exception&) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Copies an object of class -\tcode{bad_exception}. -\end{itemdescr} - \indexlibrarymember{what}{bad_exception}% \begin{itemdecl} const char* what() const noexcept override; @@ -3688,7 +3566,7 @@ The type \tcode{exception_ptr} can be used to refer to an exception object. \pnum -\tcode{exception_ptr} shall satisfy the requirements of +\tcode{exception_ptr} meets the requirements of \oldconcept{NullablePointer} (\tref{nullablepointer}). \pnum @@ -3752,7 +3630,7 @@ \begin{itemdescr} \pnum -\requires \tcode{p} shall not be a null pointer. +\expects \tcode{p} is not a null pointer. \pnum \throws The exception object to which \tcode{p} refers. @@ -3852,7 +3730,7 @@ Let \tcode{U} be \tcode{decay_t}. \pnum -\requires \tcode{U} shall be \oldconcept{CopyConstructible}. +\expects \tcode{U} meets the \oldconcept{CopyConstructible} requirements. \pnum \throws @@ -3891,7 +3769,7 @@ \indextext{signal-safe!\idxcode{initializer_list} functions}% All functions specified in this subclause are signal-safe\iref{support.signal}. -\rSec2[initializer_list.syn]{Header \tcode{} synopsis} +\rSec2[initializer.list.syn]{Header \tcode{} synopsis} \indexlibrary{\idxcode{initializer_list}}% \indexlibrary{\idxcode{begin}}% \indexlibrary{\idxcode{end}}% @@ -3941,9 +3819,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects Constructs an empty \tcode{initializer_list} object. - \pnum \ensures \tcode{size() == 0}. \end{itemdescr} @@ -4960,6 +4835,493 @@ \end{itemize} \end{itemdescr} +\rSec1[support.coroutine]{Coroutines} + +\pnum +The header +\tcode{} +defines several types providing +compile and run-time support for +coroutines in a \Cpp{} program. + +\rSec2[coroutine.syn]{Header \tcode{} synopsis} + +\indextext{\idxhdr{coroutine}}% +\indexlibrary{\idxhdr{coroutine}}% +\indexlibrary{\idxcode{noop_coroutine_handle}}% +\begin{codeblock} +namespace std { + // \ref{coroutine.traits}, coroutine traits + template + struct coroutine_traits; + + // \ref{coroutine.handle}, coroutine handle + template + struct coroutine_handle; + + // \ref{coroutine.handle.compare}, comparison operators + constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept; + constexpr bool operator!=(coroutine_handle<> x, coroutine_handle<> y) noexcept; + constexpr bool operator<(coroutine_handle<> x, coroutine_handle<> y) noexcept; + constexpr bool operator>(coroutine_handle<> x, coroutine_handle<> y) noexcept; + constexpr bool operator<=(coroutine_handle<> x, coroutine_handle<> y) noexcept; + constexpr bool operator>=(coroutine_handle<> x, coroutine_handle<> y) noexcept; + + // \ref{coroutine.handle.hash}, hash support + template struct hash; + template struct hash>; + + // \ref{coroutine.noop}, no-op coroutines + struct noop_coroutine_promise; + + template<> struct coroutine_handle; + using noop_coroutine_handle = coroutine_handle; + + noop_coroutine_handle noop_coroutine() noexcept; + + // \ref{coroutine.trivial.awaitables}, trivial awaitables + struct suspend_never; + struct suspend_always; +} +\end{codeblock} + +\rSec2[coroutine.traits]{Coroutine traits} + +\pnum +This subclause defines requirements on classes representing +\term{coroutine traits}, +and defines the class template +\tcode{coroutine_traits} +that satisfies those requirements. + +\rSec3[coroutine.traits.primary]{Class template \tcode{coroutine_traits}} + +\pnum +The header \tcode{} defines the primary template +\tcode{coroutine_traits} such that +if \tcode{ArgTypes} is a parameter pack of types and +if the \grammarterm{qualified-id} \tcode{R::promise_type} is valid and +denotes a type\iref{temp.deduct}, +then \tcode{coroutine_traits} has the following publicly +accessible member: + +\begin{codeblock} + using promise_type = typename R::promise_type; +\end{codeblock} + +Otherwise, \tcode{coroutine_traits} has no members. + +\pnum +Program defined specializations of this template shall define a publicly +accessible nested type named \tcode{promise_type}. + +\rSec2[coroutine.handle]{Class template \tcode{coroutine_handle}} + +\indexlibrary{\idxcode{coroutine_handle}}% +\begin{codeblock} +namespace std { + template<> + struct coroutine_handle + { + // \ref{coroutine.handle.con}, construct/reset + constexpr coroutine_handle() noexcept; + constexpr coroutine_handle(nullptr_t) noexcept; + coroutine_handle& operator=(nullptr_t) noexcept; + + // \ref{coroutine.handle.export.import}, export/import + constexpr void* address() const noexcept; + constexpr static coroutine_handle from_address(void* addr); + + // \ref{coroutine.handle.observers}, observers + constexpr explicit operator bool() const noexcept; + bool done() const; + + // \ref{coroutine.handle.resumption}, resumption + void operator()() const; + void resume() const; + void destroy() const; + + private: + void* ptr; // \expos + }; + + template + struct coroutine_handle : coroutine_handle<> + { + // \ref{coroutine.handle.con}, construct/reset + using coroutine_handle<>::coroutine_handle; + static coroutine_handle from_promise(Promise&); + coroutine_handle& operator=(nullptr_t) noexcept; + + // \ref{coroutine.handle.export.import}, export/import + constexpr static coroutine_handle from_address(void* addr); + + // \ref{coroutine.handle.promise}, promise access + Promise& promise() const; + }; +} +\end{codeblock} + +\pnum +An object of type +\tcode{coroutine_handle} is called a \term{coroutine handle} +and can be used to refer to a suspended or executing coroutine. +A default-constructed \tcode{coroutine_handle} object does not refer to any +coroutine. + +\pnum +If a program declares an explicit or partial specialization of +\tcode{coroutine_handle}, the behavior is undefined. + +\rSec3[coroutine.handle.con]{Construct/reset} + +\indexlibrary{\idxcode{coroutine_handle}!constructor}% +\begin{itemdecl} +constexpr coroutine_handle() noexcept; +constexpr coroutine_handle(nullptr_t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures \tcode{address() == nullptr}. +\end{itemdescr} + +\indexlibrarymember{from_promise}{coroutine_handle}% +\begin{itemdecl} +static coroutine_handle from_promise(Promise& p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} is a reference to a promise object of a coroutine. + +\pnum +\returns A coroutine handle \tcode{h} referring to the coroutine. + +\pnum +\ensures \tcode{addressof(h.promise()) == addressof(p)}. +\end{itemdescr} + +\indexlibrarymember{operator=}{coroutine_handle}% +\begin{itemdecl} +coroutine_handle& operator=(nullptr_t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures \tcode{address() == nullptr}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\rSec3[coroutine.handle.export.import]{Export/import} + +\indexlibrarymember{address}{coroutine_handle}% +\begin{itemdecl} +constexpr void* address() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ptr}. +\end{itemdescr} + +\indexlibrarymember{from_address}{coroutine_handle}% +\begin{itemdecl} +constexpr static coroutine_handle<> coroutine_handle<>::from_address(void* addr); +constexpr static coroutine_handle coroutine_handle::from_address(void* addr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{addr} was obtained via a prior call to \tcode{address}. + +\pnum +\ensures \tcode{from_address(address()) == *this}. +\end{itemdescr} + +\rSec3[coroutine.handle.observers]{Observers} + +\indexlibrarymember{operator bool}{coroutine_handle}% +\begin{itemdecl} +constexpr explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{address() != nullptr}. +\end{itemdescr} + +\indexlibrarymember{done}{coroutine_handle}% +\begin{itemdecl} +bool done() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{*this} refers to a suspended coroutine. + +\pnum +\returns \tcode{true} if the coroutine is suspended at its +final suspend point, otherwise \tcode{false}. +\end{itemdescr} + +\rSec3[coroutine.handle.resumption]{Resumption} + +\pnum +Resuming a coroutine via \tcode{resume}, \tcode{operator()}, or \tcode{destroy} +on an execution agent other than the one on which it was suspended +has implementation-defined behavior unless +each execution agent is either +an instance of \tcode{std::thread} or +the thread that executes \tcode{main}. +\begin{note} +A coroutine that is resumed on a different execution agent should +avoid relying on consistent thread identity throughout, such as holding +a mutex object across a suspend point. +\end{note} +\begin{note} +A concurrent resumption of the coroutine may result in a data race. +\end{note} + +\indexlibrarymember{operator()}{coroutine_handle}% +\indexlibrarymember{resume}{coroutine_handle}% +\begin{itemdecl} +void operator()() const; +void resume() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{*this} refers to a suspended coroutine. + +\pnum +\effects Resumes the execution of the coroutine. If the coroutine +was suspended at its final suspend point, behavior is undefined. +\end{itemdescr} + +\indexlibrarymember{destroy}{coroutine_handle}% +\begin{itemdecl} +void destroy() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{*this} refers to a suspended coroutine. + +\pnum +\effects Destroys the coroutine\iref{dcl.fct.def.coroutine}. +\end{itemdescr} + +\rSec3[coroutine.handle.promise]{Promise access} + +\indexlibrarymember{promise}{coroutine_handle}% +\begin{itemdecl} +Promise& promise() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{*this} refers to a coroutine. + +\pnum +\returns A reference to the promise of the coroutine. +\end{itemdescr} + +\rSec3[coroutine.handle.compare]{Comparison operators} + +\indexlibrarymember{operator==}{coroutine_handle}% +\indexlibrarymember{operator"!=}{coroutine_handle}% +\begin{itemdecl} +constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns \tcode{x.address() == y.address()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{coroutine_handle}% +\indexlibrarymember{operator>}{coroutine_handle}% +\indexlibrarymember{operator<=}{coroutine_handle}% +\indexlibrarymember{operator>=}{coroutine_handle}% +\begin{itemdecl} +constexpr bool operator<(coroutine_handle<> x, coroutine_handle<> y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns \tcode{less<>()(x.address(), y.address())}. +\end{itemdescr} + +\rSec3[coroutine.handle.hash]{Hash support} + +\indexlibrary{\idxcode{hash}!\idxcode{coroutine_handle}}% +\begin{itemdecl} +template struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum The specialization is enabled\iref{unord.hash}. +\end{itemdescr} + +\rSec2[coroutine.noop]{No-op coroutines} + +\rSec3[coroutine.promise.noop]{Class \tcode{noop_coroutine_promise}} + +\indexlibrary{\idxcode{noop_coroutine_promise}}% +\begin{itemdecl} +struct noop_coroutine_promise {}; +\end{itemdecl} + +\begin{itemdescr} +\pnum The class \tcode{noop_coroutine_promise} defines the promise type for +the coroutine referred to +by \tcode{noop_coroutine_handle}\iref{coroutine.syn}. +\end{itemdescr} + +\rSec3[coroutine.handle.noop]{Class \tcode{coroutine_handle}} + +\indexlibrary{\idxcode{coroutine_handle}}% +\begin{codeblock} +namespace std { + template<> + struct coroutine_handle : coroutine_handle<> + { + // \ref{coroutine.handle.noop.observers}, observers + constexpr explicit operator bool() const noexcept; + constexpr bool done() const noexcept; + + // \ref{coroutine.handle.noop.resumption}, resumption + constexpr void operator()() const noexcept; + constexpr void resume() const noexcept; + constexpr void destroy() const noexcept; + + // \ref{coroutine.handle.noop.promise}, promise access + noop_coroutine_promise& promise() const noexcept; + + // \ref{coroutine.handle.noop.address}, address + constexpr void* address() const noexcept; + private: + coroutine_handle(@\unspec@); + }; +} +\end{codeblock} + +\rSec4[coroutine.handle.noop.observers]{Observers} + +\indexlibrarymember{operator bool}{coroutine_handle}% +\begin{itemdecl} +constexpr explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{done}{coroutine_handle}% +\begin{itemdecl} +constexpr bool done() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns \tcode{false}. +\end{itemdescr} + +\rSec4[coroutine.handle.noop.resumption]{Resumption} + +\indexlibrarymember{operator()}{coroutine_handle}% +\indexlibrarymember{resume}{coroutine_handle}% +\indexlibrarymember{destroy}{coroutine_handle}% +\begin{itemdecl} +constexpr void operator()() const noexcept; +constexpr void resume() const noexcept; +constexpr void destroy() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects None. + +\pnum +\remarks +If \tcode{noop_coroutine_handle} is converted to \tcode{coroutine_handle<>}, +calls to \tcode{operator()}, \tcode{resume} and \tcode{destroy} on that handle +will also have no observable effects. +\end{itemdescr} + +\rSec4[coroutine.handle.noop.promise]{Promise access} + +\indexlibrarymember{promise}{coroutine_handle}% +\begin{itemdecl} +noop_coroutine_promise& promise() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns A reference to the promise object associated with this +coroutine handle. +\end{itemdescr} + +\rSec4[coroutine.handle.noop.address]{Address} + +\indexlibrarymember{address}{coroutine_handle}% +\begin{itemdecl} +constexpr void* address() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns \tcode{ptr}. + +\pnum \remarks A \tcode{noop_coroutine_handle}'s \tcode{ptr} is always a +non-null pointer value. +\end{itemdescr} + +\rSec3[coroutine.noop.coroutine]{Function \tcode{noop_coroutine}} + +\indexlibrary{noop_coroutine}% +\begin{itemdecl} +noop_coroutine_handle noop_coroutine() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \returns A handle to a coroutine that has no observable effects +when resumed or destroyed. + +\pnum \remarks A handle returned from \tcode{noop_coroutine} may or may not +compare equal to a handle returned from another invocation +of \tcode{noop_coroutine}. +\end{itemdescr} + +\rSec2[coroutine.trivial.awaitables]{Trivial awaitables} + +\indexlibrary{\idxcode{suspend_never}}% +\indexlibrarymember{await_ready}{suspend_never}% +\indexlibrarymember{await_suspend}{suspend_never}% +\indexlibrarymember{await_resume}{suspend_never}% +\indexlibrary{\idxcode{suspend_always}}% +\indexlibrarymember{await_ready}{suspend_always}% +\indexlibrarymember{await_suspend}{suspend_always}% +\indexlibrarymember{await_resume}{suspend_always}% +\begin{codeblock} +namespace std { + struct suspend_never { + constexpr bool await_ready() const noexcept { return true; } + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + constexpr void await_resume() const noexcept {} + }; + struct suspend_always { + constexpr bool await_ready() const noexcept { return false; } + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + constexpr void await_resume() const noexcept {} + }; +} +\end{codeblock} + +\pnum +\begin{note} +The types \tcode{suspend_never} and \tcode{suspend_always} can be used +to indicate that an \grammarterm{await-expression} should either never +suspend or always suspend, and in either case not produce a value. +\end{note} + \rSec1[support.runtime]{Other runtime support} \pnum @@ -5078,6 +5440,8 @@ behavior if replacing the \tcode{setjmp} and \tcode{longjmp} by \tcode{catch} and \tcode{throw} would invoke any non-trivial destructors for any automatic objects. +A call to \tcode{setjmp} or \tcode{longjmp} has undefined +behavior if invoked in a suspension context of a coroutine\iref{expr.await}. \xrefc{7.13} diff --git a/source/templates.tex b/source/templates.tex index 8ce5e969de..69e946c552 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -21,7 +21,7 @@ \begin{bnf} \nontermdef{template-head}\br - \terminal{template} \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause} + \keyword{template} \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause} \end{bnf} \begin{bnf} @@ -32,7 +32,7 @@ \begin{bnf} \nontermdef{requires-clause}\br - \terminal{requires} constraint-logical-or-expression + \keyword{requires} constraint-logical-or-expression \end{bnf} \begin{bnf} @@ -49,7 +49,7 @@ \begin{bnf} \nontermdef{concept-definition}\br - \terminal{concept} concept-name \terminal{=} constraint-expression \terminal{;} + \keyword{concept} concept-name \terminal{=} constraint-expression \terminal{;} \end{bnf} \begin{bnf} @@ -130,6 +130,8 @@ A \grammarterm{template-declaration} can appear only as a namespace scope or class scope declaration. +Its \grammarterm{declaration} shall not be an +\grammarterm{export-declaration}. In a function template declaration, the last component of the \grammarterm{declarator-id} shall not be a @@ -276,8 +278,8 @@ \begin{bnf} \nontermdef{type-parameter-key}\br - \terminal{class}\br - \terminal{typename} + \keyword{class}\br + \keyword{typename} \end{bnf} \begin{note} The \tcode{>} token following the @@ -369,11 +371,8 @@ shall have one of the following (optionally cv-qualified) types: \begin{itemize} -\item a type that is literal, -has strong structural equality\iref{class.compare.default}, -has no \tcode{mutable} or \tcode{volatile} subobjects, -and in which if there is a defaulted member \tcode{operator<=>}, -then it is declared public, +\item a literal type that + has strong structural equality\iref{class.compare.default}, \item an lvalue reference type, @@ -416,7 +415,7 @@ \end{note} \begin{example} \begin{codeblock} -struct A { friend auto operator<=>(const A&, const A&) = default; }; +struct A { friend bool operator==(const A&, const A&) = default; }; template void f() { i++; // error: change of template-parameter value @@ -733,7 +732,7 @@ A name is also considered to refer to a template if it is an \grammarterm{unqualified-id} followed by a \tcode{<} -and name lookup finds either one or more functions or finds nothing. +and name lookup either finds one or more functions or finds nothing. \pnum \indextext{\idxcode{<}!template and}% @@ -1280,7 +1279,7 @@ struct A { constexpr A(const char*) {} - friend auto operator<=>(const A&, const A&) = default; + friend bool operator==(const A&, const A&) = default; }; X z; // OK, string literal is a constructor argument to \tcode{A} @@ -1945,7 +1944,7 @@ have the same type and value after conversion to the type of the \grammarterm{template-parameter}, where they are considered to have the same value if they compare equal -with \tcode{operator<=>}, and} +with the \tcode{==} operator\iref{expr.eq}, and} \item {their corresponding template \grammarterm{template-argument}{s} refer to the same template.} \end{itemize} @@ -2182,7 +2181,7 @@ }; \end{codeblock} -declares three function templates. +declares three member functions of a class template. The subscript function might be defined like this: \begin{codeblock} @@ -2967,8 +2966,9 @@ \pnum When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include -default arguments, nor shall the inline specifier be used in such a -declaration. +default arguments, nor shall +the \tcode{inline}, \tcode{constexpr}, or \tcode{consteval} specifiers +be used in such a declaration. \pnum A non-template friend declaration shall not have a \grammarterm{requires-clause}. @@ -3337,7 +3337,7 @@ The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization. -A class template specialization is a distinct template. +A class template partial specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template. Class template partial specialization members that are used in a way that @@ -4015,8 +4015,8 @@ \begin{bnf} \nontermdef{typename-specifier}\br - \terminal{typename} nested-name-specifier identifier\br - \terminal{typename} nested-name-specifier \terminal{\opt{template}} simple-template-id + \keyword{typename} nested-name-specifier identifier\br + \keyword{typename} nested-name-specifier \terminal{\opt{template}} simple-template-id \end{bnf} \pnum @@ -4379,8 +4379,10 @@ as a \grammarterm{template-argument} for a template \grammarterm{template-parameter}, or as the final identifier in the \grammarterm{elaborated-type-specifier} of a friend class template declaration, -it refers to the -class template itself. Otherwise, it is equivalent to the \grammarterm{template-name} +it is a \grammarterm{template-name} that refers to the +class template itself. +Otherwise, it is a \grammarterm{type-name} +equivalent to the \grammarterm{template-name} followed by the \grammarterm{template-parameter}{s} of the class template enclosed in \tcode{<>}. @@ -4410,8 +4412,8 @@ \pnum The injected-class-name of a class template or class -template specialization can be used either -as a \grammarterm{template-name} or a \grammarterm{type-name} +template specialization can be used as either +a \grammarterm{template-name} or a \grammarterm{type-name} wherever it is in scope. \begin{example} \begin{codeblock} @@ -4583,6 +4585,8 @@ (that is, its value when evaluated as a constant expression\iref{expr.const} may depend on a template parameter) as described in this subclause. + +\pnum In an expression of the form: \begin{ncsimplebnf} @@ -4619,10 +4623,12 @@ If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. +\begin{note} Such names are unbound and are looked up at the point of the template instantiation\iref{temp.point} in both the context of the template definition and the -context of the point of instantiation. +context of the point of instantiation\iref{temp.dep.candidate}. +\end{note} \pnum \begin{example} @@ -4926,8 +4932,8 @@ of the \grammarterm{id-expression} does not find a member of a class that is the current instantiation or a non-dependent base class thereof; or -\item the type of the object expression is dependent and is not the current -instantiation. +\item the type of the object expression is not the current instantiation +and the object expression is type-dependent. \end{itemize} \end{itemize} @@ -5078,6 +5084,11 @@ \mname{func}\iref{dcl.fct.def.general}, where any enclosing function is a template, a member of a class template, or a generic lambda, +\item +the \grammarterm{identifier} introduced in +a postcondition\iref{dcl.attr.contract} to represent the result of +a templated function whose declared return type contains a placeholder type, + \item a \grammarterm{template-id} @@ -5109,12 +5120,12 @@ \begin{ncsimplebnf} simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br -\terminal{\opt{::} new} \opt{new-placement} new-type-id \opt{new-initializer}\br -\terminal{\opt{::} new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer}\br -\terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br -\terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br -\terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br -\terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br +\opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer}\br +\opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer}\br +\keyword{dynamic_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br +\keyword{static_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br +\keyword{const_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br +\keyword{reinterpret_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br \terminal{(} type-id \terminal{)} cast-expression \end{ncsimplebnf} @@ -5124,16 +5135,16 @@ \begin{ncsimplebnf} literal\br -\terminal{sizeof} unary-expression\br -\terminal{sizeof (} type-id \terminal{)}\br -\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br -\terminal{alignof (} type-id \terminal{)}\br -\terminal{typeid (} expression \terminal{)}\br -\terminal{typeid (} type-id \terminal{)}\br -\terminal{\opt{::} delete} cast-expression\br -\terminal{\opt{::} delete [ ]} cast-expression\br -\terminal{throw} \opt{assignment-expression}\br -\terminal{noexcept} \terminal{(} expression \terminal{)} +\keyword{sizeof} unary-expression\br +\keyword{sizeof} \terminal{(} type-id \terminal{)}\br +\keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br +\keyword{alignof} \terminal{(} type-id \terminal{)}\br +\keyword{typeid} \terminal{(} expression \terminal{)}\br +\keyword{typeid} \terminal{(} type-id \terminal{)}\br +\opt{\terminal{::}} \keyword{delete} cast-expression\br +\opt{\terminal{::}} \keyword{delete} \terminal{[ ]} cast-expression\br +\keyword{throw} \opt{assignment-expression}\br +\keyword{noexcept} \terminal{(} expression \terminal{)} \end{ncsimplebnf} \begin{note} For the standard library macro \tcode{offsetof}, @@ -5214,12 +5225,12 @@ is dependent: \begin{ncsimplebnf} -\terminal{sizeof} unary-expression\br -\terminal{sizeof (} type-id \terminal{)}\br -\terminal{typeid (} expression \terminal{)}\br -\terminal{typeid (} type-id \terminal{)}\br -\terminal{alignof (} type-id \terminal{)}\br -\terminal{noexcept} \terminal{(} expression \terminal{)} +\keyword{sizeof} unary-expression\br +\keyword{sizeof} \terminal{(} type-id \terminal{)}\br +\keyword{typeid} \terminal{(} expression \terminal{)}\br +\keyword{typeid} \terminal{(} type-id \terminal{)}\br +\keyword{alignof} \terminal{(} type-id \terminal{)}\br +\keyword{noexcept} \terminal{(} expression \terminal{)} \end{ncsimplebnf} \begin{note} For the standard library macro \tcode{offsetof}, @@ -5238,9 +5249,9 @@ \begin{ncsimplebnf} simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br -\terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br -\terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br -\terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br +\keyword{static_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br +\keyword{const_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br +\keyword{reinterpret_cast} \terminal{<} type-id \terminal{> (} expression \terminal{)}\br \terminal{(} type-id \terminal{)} cast-expression \end{ncsimplebnf} @@ -5248,7 +5259,7 @@ Expressions of the following form are value-dependent: \begin{ncsimplebnf} -\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br +\keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br fold-expression \end{ncsimplebnf} @@ -5317,21 +5328,6 @@ \end{example} \rSec2[temp.dep.res]{Dependent name resolution} - -\pnum -\indextext{name!dependent}% -In resolving dependent names, names from the following sources are considered: - -\begin{itemize} -\item -Declarations that are visible at the point of definition of the -template. -\item -Declarations from namespaces associated with the types of the -function arguments both from the instantiation context\iref{temp.point} -and from the definition context. -\end{itemize} - \rSec3[temp.point]{Point of instantiation} \pnum @@ -5394,19 +5390,28 @@ point for the specialization or specializations specified by the explicit instantiation. -\pnum -The instantiation context of an expression that depends on the template -arguments is the set of declarations with external linkage declared prior to the -point of instantiation of the template specialization in the same translation -unit. - \pnum A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition -to the points of instantiation described above, for any such specialization -that has a point of instantiation within the translation unit, the end of the -translation unit is also considered a point of instantiation. +to the points of instantiation described above, +\begin{itemize} +\item +for any such +specialization that has a point of instantiation within the +\grammarterm{top-level-declaration-seq} of the +translation unit, +prior to the \grammarterm{private-module-fragment} (if any), +the point after the \grammarterm{top-level-declaration-seq} +of the \grammarterm{translation-unit} +is also considered a point of instantiation, +and +\item +for any such specialization that has a point of instantiation +within the \grammarterm{private-module-fragment}, +the end of the translation unit is also +considered a point of instantiation. +\end{itemize} A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple @@ -5422,19 +5427,13 @@ For a function call where the \grammarterm{postfix-expression} is a dependent name, the candidate functions are found using the usual lookup -rules~(\ref{basic.lookup.unqual}, \ref{basic.lookup.argdep}) except that: - -\begin{itemize} -\item -For the part of the lookup using unqualified name lookup\iref{basic.lookup.unqual}, -only function declarations -from the template definition context are found. -\item +rules from the template definition context +(\ref{basic.lookup.unqual}, \ref{basic.lookup.argdep}). +\begin{note} For the part of the lookup using associated namespaces\iref{basic.lookup.argdep}, -only function declarations found in either the template -definition context or the template instantiation context are found. -\end{itemize} - +function declarations found in the template instantiation context +are found by this lookup, as described in \ref{basic.lookup.argdep}. +\end{note} If the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with @@ -5442,6 +5441,166 @@ not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior. +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"X.h"}} +namespace Q { + struct X { }; +} +\end{codeblocktu} + +\begin{codeblocktu}{Source file \tcode{"G.h"}} +namespace Q { + void g_impl(X, X); +} +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{M1}} +module; +#include "X.h" +#include "G.h" +export module M1; +export template +void g(T t) { + g_impl(t, Q::X{ }); // ADL in definition context finds \tcode{Q::g_impl}, \tcode{g_impl} not discarded +} +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{M2}} +module; +#include "X.h" +export module M2; +import M1; +void h(Q::X x) { + g(x); // OK +} +\end{codeblocktu} +\end{example} + +\pnum +\begin{example} +\begin{codeblocktu}{Module interface unit of \tcode{Std}} +export module Std; +export template +void indirect_swap(Iter lhs, Iter rhs) +{ + swap(*lhs, *rhs); // \tcode{swap} not found by unqualified lookup, can be found only via ADL +} +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{M}} +export module M; +import Std; + +struct S { /* ...*/ }; +void swap(S&, S&); // \#1 + +void f(S* p, S* q) +{ + indirect_swap(p, q); // finds \#1 via ADL in instantiation context +} +\end{codeblocktu} +\end{example} + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"X.h"}} +struct X { /* ... */ }; +X operator+(X, X); +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{F}} +export module F; +export template +void f(T t) { + t + t; +} +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{M}} +module; +#include "X.h" +export module M; +import F; +void g(X x) { + f(x); // OK: instantiates \tcode{f} from \tcode{F}, + // \tcode{operator+} is visible in instantiation context +} +\end{codeblocktu} +\end{example} + +\pnum +\begin{example} +\begin{codeblocktu}{Module interface unit of \tcode{A}} +export module A; +export template +void f(T t) { + cat(t, t); // \#1 + dog(t, t); // \#2 +} +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{B}} +export module B; +import A; +export template +void g(T t, U u) { + f(t); +} +\end{codeblocktu} + +\begin{codeblocktu}{Source file \tcode{"foo.h"}, not an importable header} +struct foo { + friend int cat(foo, foo); +}; +int dog(foo, foo); +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{C1}} +module; +#include "foo.h" // \tcode{dog} not referenced, discarded +export module C1; +import B; +export template +void h(T t) { + g(foo{ }, t); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit} +import C1; +void i() { + h(0); // error: \tcode{dog} not found at \#2 +} +\end{codeblocktu} + +\begin{codeblocktu}{Importable header \tcode{"bar.h"}} +struct bar { + friend int cat(bar, bar); +}; +int dog(bar, bar); +\end{codeblocktu} + +\begin{codeblocktu}{Module interface unit of \tcode{C2}} +module; +#include "bar.h" // imports header unit \tcode{"bar.h"} +export module C2; +import B; +export template +void j(T t) { + g(bar{ }, t); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit} +import C2; +void k() { + j(0); // OK, \tcode{dog} found in instantiation context: + // visible at end of module interface unit of \tcode{C2} +} +\end{codeblocktu} +\end{example} + \rSec2[temp.inject]{Friend names declared within a class template} \pnum @@ -5478,7 +5637,8 @@ \pnum \indextext{specialization!template}% -The act of instantiating a function, a class, a member of a class template or +The act of instantiating a function, a variable, +a class, a member of a class template, or a member template is referred to as \defn{template instantiation}. @@ -5501,12 +5661,14 @@ \pnum An explicit specialization may be declared for a function template, -a class template, a member of a class template or a member template. +a variable template, a class template, a member of a class template, or +a member template. An explicit specialization declaration is introduced by \tcode{template<>}. -In an explicit specialization declaration for a class template, +In an explicit specialization declaration for +a variable template, a class template, a member of a class template or a class member template, -the name of the class that is explicitly specialized shall be a +the name of the variable or class that is explicitly specialized shall be a \grammarterm{simple-template-id}. In the explicit specialization declaration for a function template or a member function template, @@ -5538,7 +5700,7 @@ An instantiated template specialization can be either implicitly instantiated\iref{temp.inst} for a given argument list or be explicitly instantiated\iref{temp.explicit}. -A specialization is a class, function, or class member that is either +A specialization is a class, variable, function, or class member that is either instantiated or explicitly specialized\iref{temp.expl.spec}. \pnum @@ -6063,7 +6225,7 @@ \begin{bnf} \nontermdef{explicit-instantiation}\br - \terminal{\opt{extern}} \terminal{template} declaration + \opt{\keyword{extern}} \keyword{template} declaration \end{bnf} There are two forms of explicit instantiation: an explicit instantiation @@ -6334,7 +6496,7 @@ \begin{bnf} \nontermdef{explicit-specialization}\br - \terminal{template < >} declaration + \keyword{template} \terminal{< >} declaration \end{bnf} \begin{example} @@ -6815,7 +6977,8 @@ \pnum \indextext{specification!template argument}% Template arguments can be specified when referring to a function -template specialization by qualifying the function template +template specialization that is not a specialization of a constructor template +by qualifying the function template name with the list of \grammarterm{template-argument}{s} in the same way as @@ -6840,6 +7003,11 @@ \end{codeblock} \end{example} +\pnum +Template arguments shall not be specified +when referring to a specialization of +a constructor template~(\ref{class.ctor}, \ref{class.qual}). + \pnum A template argument list may be specified when referring to a specialization of a function template @@ -7346,14 +7514,15 @@ \tcode{A}) as described below. If removing references and cv-qualifiers from \tcode{P} gives -\tcode{std::initializer_list} -or \tcode{P$'$[N]} -for some \tcode{P$'$} and \tcode{N} and the +\tcode{std::initializer_list} +or $\tcode{P}'\tcode{[N]}$ +for some $\tcode{P}'$ and \tcode{N} and the argument is a non-empty initializer list\iref{dcl.init.list}, then deduction is -performed instead for each element of the initializer list, taking -\tcode{P$'$} as a function template parameter type and the initializer -element as its argument, -and in the \tcode{P$'$[N]} case, if \tcode{N} is a non-type template parameter, +performed instead for each element of the initializer list independently, +taking $\tcode{P}'$ +as separate function template parameter types $\tcode{P}'_i$ +and the $i^\text{th}$ initializer element as the corresponding argument. +In the $\tcode{P}'\tcode{[N]}$ case, if \tcode{N} is a non-type template parameter, \tcode{N} is deduced from the length of the initializer list. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context\iref{temp.deduct.type}. @@ -7382,6 +7551,14 @@ template void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, \tcode{T} is \tcode{Aggr}, \tcode{N} is \tcode{3} + +template void o(T (* const (&)[N])(T)) { } +int f1(int); +int f4(int); +char f4(char); +o({ &f1, &f4 }); // OK, \tcode{T} deduced as \tcode{int} from first element, nothing + // deduced from second element, \tcode{N} deduced as \tcode{2} +o({ &f1, static_cast(&f4) }); // error: conflicting deductions for \tcode{T} \end{codeblock} \end{example} For a function parameter pack that occurs at the end @@ -7535,7 +7712,7 @@ \grammarterm{simple-template-id}, then the transformed \tcode{A} -can be a derived class of the +can be a derived class \tcode{D} of the deduced \tcode{A}. Likewise, if @@ -7544,8 +7721,28 @@ \grammarterm{simple-template-id}, the transformed \tcode{A} can be a pointer to a -derived class pointed to by the deduced +derived class \tcode{D} pointed to by the deduced \tcode{A}. +However, if there is a class \tcode{C} that is +a (direct or indirect) base class of \tcode{D} and +derived (directly or indirectly) from a class \tcode{B} and +that would be a valid deduced \tcode{A}, +the deduced \tcode{A} cannot be \tcode{B} or pointer to \tcode{B}, +respectively. +\begin{example} +\begin{codeblock} +template struct X; +template <> struct X<> {}; +template + struct X : X {}; +struct D : X {}; + +template +int f(const X&); +int x = f(D()); // calls \tcode{f}, not \tcode{f<>} + // \tcode{B} is \tcode{X<>}, \tcode{C} is \tcode{X} +\end{codeblock} +\end{example} \end{itemize} \pnum @@ -7740,11 +7937,11 @@ \item If the original \tcode{A} is a function pointer type, \tcode{A} can be ``pointer to function'' -even if the deduced \tcode{A} is ``pointer to noexcept function''. +even if the deduced \tcode{A} is ``pointer to \tcode{noexcept} function''. \item If the original \tcode{A} is a pointer-to-member-function type, \tcode{A} can be ``pointer to member of type function'' -even if the deduced \tcode{A} is ``pointer to member of type noexcept function''. +even if the deduced \tcode{A} is ``pointer to member of type \tcode{noexcept} function''. \item The deduced \tcode{A} can be another pointer or pointer-to-member type that @@ -7758,44 +7955,6 @@ \tcode{A}, the type deduction fails. -\pnum -When the deduction process requires a qualification conversion for a -pointer or pointer-to-member type as described above, the following -process is used to determine the deduced template argument values: - -If -\tcode{A} -is a type -\begin{indented} -$\cv{}_{1,0}$ ``pointer to $\ldots$'' $\cv{}_{1,n-1}$ ``pointer to'' -$\cv{}_{1,n}$ \tcode{T1} -\end{indented} -and -\tcode{P} -is a type -\begin{indented} -$\cv{}_{2,0}$ ``pointer to $\ldots$'' $\cv{}_{2,n-1}$ ``pointer to'' -$\cv{}_{2,n}$ \tcode{T2}, -\end{indented} -then the cv-unqualified -\tcode{T1} -and -\tcode{T2} -are used as the types of -\tcode{A} -and -\tcode{P} -respectively for type deduction. -\begin{example} -\begin{codeblock} -struct A { - template operator T***(); -}; -A a; -const int * const * const * p1 = a; // \tcode{T} deduced as \tcode{int}, not \tcode{const int} -\end{codeblock} -\end{example} - \rSec3[temp.deduct.partial]{Deducing template arguments during partial ordering} \pnum @@ -8829,7 +8988,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \opt{\terminal{explicit}} template-name \terminal{(} parameter-declaration-clause \terminal{) ->} simple-template-id \terminal{;} + \opt{\keyword{explicit}} template-name \terminal{(} parameter-declaration-clause \terminal{) ->} simple-template-id \terminal{;} \end{bnf} \pnum diff --git a/source/threads.tex b/source/threads.tex index c2ddd2b54c..72111de61a 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -843,7 +843,7 @@ } \end{codeblock} -\rSec2[shared_mutex.syn]{Header \tcode{} synopsis} +\rSec2[shared.mutex.syn]{Header \tcode{} synopsis} \indexhdr{shared_mutex}% \begin{codeblock} @@ -2857,7 +2857,7 @@ \pnum Condition variable construction and destruction need not be synchronized. -\rSec2[condition_variable.syn]{Header \tcode{} synopsis} +\rSec2[condition.variable.syn]{Header \tcode{} synopsis} \indexhdr{condition_variable}% \indexlibrary{\idxcode{cv_status}}% @@ -3692,7 +3692,7 @@ \returns \tcode{error_condition(static_cast(e), future_category())}. \end{itemdescr} -\rSec2[futures.future_error]{Class \tcode{future_error}} +\rSec2[futures.future.error]{Class \tcode{future_error}} \indexlibrary{\idxcode{future_error}}% \begin{codeblock} @@ -3849,7 +3849,7 @@ \begin{note} This explicitly specifies that the result of the shared state is visible in the objects that reference this state in the sense of data race avoidance\iref{res.on.data.races}. For example, concurrent accesses through -references returned by \tcode{shared_future::get()}\iref{futures.shared_future} +references returned by \tcode{shared_future::get()}\iref{futures.shared.future} must either use read-only operations or provide additional synchronization. \end{note} @@ -4156,7 +4156,7 @@ \effects As if by \tcode{x.swap(y)}. \end{itemdescr} -\rSec2[futures.unique_future]{Class template \tcode{future}} +\rSec2[futures.unique.future]{Class template \tcode{future}} \pnum The class template \tcode{future} defines a type for asynchronous return objects which @@ -4443,7 +4443,7 @@ \end{itemdescr} -\rSec2[futures.shared_future]{Class template \tcode{shared_future}} +\rSec2[futures.shared.future]{Class template \tcode{shared_future}} \pnum The class template \tcode{shared_future} defines a type for asynchronous return objects diff --git a/source/time.tex b/source/time.tex index 8c213eb35f..95abf28e35 100644 --- a/source/time.tex +++ b/source/time.tex @@ -1085,12 +1085,9 @@ \item \tcode{TC} satisfies the \oldconcept{Clock} requirements\iref{time.clock.req}, \item the types \tcode{TC::rep}, \tcode{TC::duration}, and \tcode{TC::time_point} -satisfy the \oldconcept{EqualityComparable} (\tref{equalitycomparable}), -\oldconcept{LessThanComparable} (\tref{lessthancomparable}), -\oldconcept{DefaultConstructible} (\tref{defaultconstructible}), -\oldconcept{\-Copy\-Con\-structible} (\tref{copyconstructible}), -\oldconcept{CopyAssignable} (\tref{copyassignable}), and -\oldconcept{Destructible} (\tref{destructible}) requirements and the requirements of +meet the \oldconcept{EqualityComparable} (\tref{equalitycomparable}) and +\oldconcept{LessThanComparable} (\tref{lessthancomparable}) +requirements and the requirements of numeric types\iref{numeric.requirements}. \begin{note} This means, in particular, that operations on these types will not throw exceptions. \end{note} @@ -1105,7 +1102,7 @@ \rSec1[time.traits]{Time-related traits} -\rSec2[time.traits.is_fp]{\tcode{treat_as_floating_point}} +\rSec2[time.traits.is.fp]{\tcode{treat_as_floating_point}} \indexlibrary{\idxcode{treat_as_floating_point}}% \begin{itemdecl} @@ -1126,7 +1123,7 @@ if it behaved like an integral type for the purpose of these conversions. \end{note} -\rSec2[time.traits.duration_values]{\tcode{duration_values}} +\rSec2[time.traits.duration.values]{\tcode{duration_values}} \indexlibrary{\idxcode{duration_values}}% \begin{itemdecl} @@ -1226,7 +1223,7 @@ The common type of two \tcode{time_point} types is a \tcode{time_point} with the same clock as the two types and the common type of their two \tcode{duration}s. -\rSec2[time.traits.is_clock]{Class template \tcode{is_clock}} +\rSec2[time.traits.is.clock]{Class template \tcode{is_clock}} \indexlibrary{\idxcode{is_clock}}% \begin{itemdecl} diff --git a/source/utilities.tex b/source/utilities.tex index cf2505cf07..e11319da09 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -42,7 +42,7 @@ throughout the rest of the library. \begin{codeblock} -#include // see \ref{initializer_list.syn} +#include // see \ref{initializer.list.syn} namespace std { // \ref{utility.swap}, swap @@ -67,7 +67,7 @@ !is_nothrow_move_constructible_v && is_copy_constructible_v, const T&, T&&> move_if_noexcept(T& x) noexcept; - // \ref{utility.as_const}, \tcode{as_const} + // \ref{utility.as.const}, \tcode{as_const} template constexpr add_const_t& as_const(T& t) noexcept; template @@ -120,8 +120,8 @@ constexpr @\seebelow@ make_pair(T1&&, T2&&); // \ref{pair.astuple}, tuple-like access to pair - template class tuple_size; - template class tuple_element; + template struct tuple_size; + template struct tuple_element; template struct tuple_size>; template struct tuple_element>; @@ -361,7 +361,7 @@ \returns \tcode{std::move(x)}. \end{itemdescr} -\rSec2[utility.as_const]{Function template \tcode{as_const}} +\rSec2[utility.as.const]{Function template \tcode{as_const}} \indexlibrary{\idxcode{as_const}}% \begin{itemdecl} @@ -1018,20 +1018,20 @@ constexpr T make_from_tuple(Tuple&& t); // \ref{tuple.helper}, tuple helper classes - template class tuple_size; // not defined - template class tuple_size; - template class tuple_size; - template class tuple_size; + template struct tuple_size; // not defined + template struct tuple_size; + template struct tuple_size; + template struct tuple_size; - template class tuple_size>; + template struct tuple_size>; - template class tuple_element; // not defined - template class tuple_element; - template class tuple_element; - template class tuple_element; + template struct tuple_element; // not defined + template struct tuple_element; + template struct tuple_element; + template struct tuple_element; template - class tuple_element>; + struct tuple_element>; template using tuple_element_t = typename tuple_element::type; @@ -1794,14 +1794,13 @@ \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} template - class tuple_size> : public integral_constant { }; + struct tuple_size> : public integral_constant { }; \end{itemdecl} \indexlibrary{\idxcode{tuple_element}}% \begin{itemdecl} template - class tuple_element> { - public: + struct tuple_element> { using type = TI; }; \end{itemdecl} @@ -1819,9 +1818,9 @@ \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} -template class tuple_size; -template class tuple_size; -template class tuple_size; +template struct tuple_size; +template struct tuple_size; +template struct tuple_size; \end{itemdecl} \begin{itemdescr} @@ -1851,15 +1850,16 @@ \pnum In addition to being available via inclusion of the \tcode{} header, the three templates are available -when any of the headers \tcode{}, \tcode{}, or \tcode{} +when any of the headers +\tcode{}, \tcode{}, \tcode{}, or \tcode{} are included. \end{itemdescr} \indexlibrary{\idxcode{tuple_element}}% \begin{itemdecl} -template class tuple_element; -template class tuple_element; -template class tuple_element; +template struct tuple_element; +template struct tuple_element; +template struct tuple_element; \end{itemdecl} \begin{itemdescr} @@ -1881,7 +1881,8 @@ \pnum In addition to being available via inclusion of the \tcode{} header, the three templates are available -when any of the headers \tcode{}, \tcode{}, or \tcode{} +when any of the headers +\tcode{}, \tcode{}, \tcode{}, or \tcode{} are included. \end{itemdescr} @@ -2171,7 +2172,7 @@ template constexpr bool operator>=(const optional&, nullopt_t) noexcept; template constexpr bool operator>=(nullopt_t, const optional&) noexcept; - // \ref{optional.comp_with_t}, comparison with \tcode{T} + // \ref{optional.comp.with.t}, comparison with \tcode{T} template constexpr bool operator==(const optional&, const U&); template constexpr bool operator==(const T&, const optional&); template constexpr bool operator!=(const optional&, const U&); @@ -3422,7 +3423,7 @@ \tcode{!x}. \end{itemdescr} -\rSec2[optional.comp_with_t]{Comparison with \tcode{T}} +\rSec2[optional.comp.with.t]{Comparison with \tcode{T}} \indexlibrarymember{operator==}{optional}% \begin{itemdecl} @@ -3785,7 +3786,7 @@ // \ref{variant.visit}, visitation template constexpr @\seebelow@ visit(Visitor&&, Variants&&...); - template + template constexpr R visit(Visitor&&, Variants&&...); // \ref{variant.monostate}, class \tcode{monostate} @@ -3870,7 +3871,7 @@ \pnum Any instance of \tcode{variant} at any given time either holds a value -of one of its alternative types, or it holds no value. +of one of its alternative types or holds no value. When an instance of \tcode{variant} holds a value of alternative type \tcode{T}, it means that a value of type \tcode{T}, referred to as the \tcode{variant} object's \defnx{contained value}{contained value!\idxcode{variant}}, is allocated within the storage of the @@ -4881,7 +4882,7 @@ \begin{itemdecl} template constexpr @\seebelow@ visit(Visitor&& vis, Variants&&... vars); -template +template constexpr R visit(Visitor&& vis, Variants&&... vars); \end{itemdecl} @@ -5060,7 +5061,7 @@ \begin{codeblock} namespace std { - // \ref{any.bad_any_cast}, class \tcode{bad_any_cast} + // \ref{any.bad.any.cast}, class \tcode{bad_any_cast} class bad_any_cast; // \ref{any.class}, class \tcode{any} @@ -5088,7 +5089,7 @@ } \end{codeblock} -\rSec2[any.bad_any_cast]{Class \tcode{bad_any_cast}} +\rSec2[any.bad.any.cast]{Class \tcode{bad_any_cast}} \indexlibrary{\idxcode{bad_any_cast}}% \begin{codeblock} @@ -5164,7 +5165,7 @@ An object of class \tcode{any} stores an instance of any type that satisfies the constructor requirements or it has no value, and this is referred to as the \defn{state} of the class \tcode{any} object. The stored instance is called the \defnx{contained value}{contained value!\idxcode{any}}. -Two states are equivalent if either they both have no value, or both have a value and the contained values are equivalent. +Two states are equivalent if either they both have no value, or they both have a value and the contained values are equivalent. \pnum The non-member \tcode{any_cast} functions provide type-safe access to the contained value. @@ -5759,8 +5760,8 @@ unsigned long to_ulong() const; unsigned long long to_ullong() const; template, - class Allocator = allocator> + class traits = char_traits, + class Allocator = allocator> basic_string to_string(charT zero = charT('0'), charT one = charT('1')) const; @@ -6221,8 +6222,8 @@ \indexlibrarymember{to_string}{bitset}% \begin{itemdecl} template, - class Allocator = allocator> + class traits = char_traits, + class Allocator = allocator> basic_string to_string(charT zero = charT('0'), charT one = charT('1')) const; \end{itemdecl} @@ -6589,22 +6590,22 @@ inline constexpr bool uses_allocator_v = uses_allocator::value; // \ref{allocator.uses.construction}, uses-allocator construction - template + template auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> @\seebelow@; - template + template auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, Tuple1&& x, Tuple2&& y) -> @\seebelow@; - template + template auto uses_allocator_construction_args(const Alloc& alloc) -> @\seebelow@; - template + template auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) -> @\seebelow@; - template + template auto uses_allocator_construction_args(const Alloc& alloc, const pair& pr) -> @\seebelow@; - template + template auto uses_allocator_construction_args(const Alloc& alloc, pair&& pr) -> @\seebelow@; - template + template T make_obj_using_allocator(const Alloc& alloc, Args&&... args); - template + template T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); // \ref{allocator.traits}, allocator traits @@ -7456,7 +7457,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> @\seebelow@; \end{itemdecl} @@ -7498,7 +7499,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, Tuple1&& x, Tuple2&& y) -> @\seebelow@; \end{itemdecl} @@ -7527,7 +7528,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc) -> @\seebelow@; \end{itemdecl} @@ -7547,7 +7548,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) -> @\seebelow@; \end{itemdecl} @@ -7568,7 +7569,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc, const pair& pr) -> @\seebelow@; \end{itemdecl} @@ -7589,7 +7590,7 @@ \indexlibrary{\idxcode{uses_allocator_construction_args}}% \begin{itemdecl} -template +template auto uses_allocator_construction_args(const Alloc& alloc, pair&& pr) -> @\seebelow@; \end{itemdecl} @@ -7610,7 +7611,7 @@ \indexlibrary{\idxcode{make_obj_using_allocator}}% \begin{itemdecl} -template +template T make_obj_using_allocator(const Alloc& alloc, Args&&... args); \end{itemdecl} @@ -7626,7 +7627,7 @@ \indexlibrary{\idxcode{uninitialized_construct_using_allocator}}% \begin{itemdecl} -template +template T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); \end{itemdecl} @@ -7936,11 +7937,11 @@ namespace std { template class allocator { public: - using value_type = T; - using size_type = size_t; - using difference_type = ptrdiff_t; + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = true_type; - using is_always_equal = true_type; + using is_always_equal = true_type; constexpr allocator() noexcept; constexpr allocator(const allocator&) noexcept; @@ -8104,8 +8105,8 @@ \tcode{\placeholdernc{voidify}}: \begin{codeblock} template - void* @\placeholdernc{voidify}@(T& ptr) noexcept { - return const_cast(static_cast(addressof(ptr))); + void* @\placeholdernc{voidify}@(T& obj) noexcept { + return const_cast(static_cast(addressof(obj))); } \end{codeblock} @@ -11850,7 +11851,7 @@ \remarks Two \tcode{shared_ptr} objects are equivalent if they store the same pointer value and -either share ownership, or both are empty. +either share ownership or are both empty. The weak form may fail spuriously. See \ref{atomics.types.operations}. \pnum @@ -12089,7 +12090,7 @@ \remarks Two \tcode{weak_ptr} objects are equivalent if they store the same pointer value and -either share ownership, or both are empty. +either share ownership or are both empty. The weak form may fail spuriously. See \ref{atomics.types.operations}. \pnum @@ -12370,7 +12371,7 @@ \indexlibrarymember{value_type}{polymorphic_allocator}% \begin{codeblock} namespace std::pmr { - template class polymorphic_allocator { + template class polymorphic_allocator { memory_resource* memory_rsrc; // \expos public: @@ -12391,6 +12392,13 @@ [[nodiscard]] Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); + void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); + void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); + template T* allocate_object(size_t n = 1); + template void deallocate_object(T* p, size_t n = 1); + template T* new_object(CtorArgs&&... ctor_args); + template void delete_object(T* p); + template void construct(T* p, Args&&... args); @@ -12491,6 +12499,119 @@ Nothing. \end{itemdescr} +\indexlibrarymember{allocate_bytes}{polymorphic_allocator}% +\begin{itemdecl} +void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return memory_rsrc->allocate(nbytes, alignment);} + +\pnum +\begin{note} +The return type is \tcode{void*} (rather than, e.g., \tcode{byte*}) +to support conversion to an arbitrary pointer type \tcode{U*} +by \tcode{static_cast}, thus facilitating construction of a \tcode{U} +object in the allocated memory. +\end{note} +\end{itemdescr} + +\indexlibrarymember{deallocate_bytes}{polymorphic_allocator}% +\begin{itemdecl} +void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{memory_rsrc->deallocate(p, nbytes, alignment)}. +\end{itemdescr} + +\indexlibrarymember{allocate_object}{polymorphic_allocator}% +\begin{itemdecl} +template + T* allocate_object(size_t n = 1); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Allocates memory suitable for holding +an array of \tcode{n} objects of type \tcode{T}, as follows: +\begin{itemize} +\item + if \tcode{SIZE_MAX / sizeof(T) < n}, throws \tcode{length_error}, +\item + otherwise equivalent to: +\begin{codeblock} +return static_cast(allocate_bytes(n*sizeof(T), alignof(T))); +\end{codeblock} +\end{itemize} + +\pnum +\begin{note} +\tcode{T} is not deduced and must therefore be provided as a template argument. +\end{note} +\end{itemdescr} + +\indexlibrarymember{deallocate_object}{polymorphic_allocator}% +\begin{itemdecl} +template + void deallocate_object(T* p, size_t n = 1); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{deallocate_bytes(p, n*sizeof(T), alignof(T))}. +\end{itemdescr} + +\indexlibrarymember{new_object}{polymorphic_allocator}% +\begin{itemdecl} +template + T* new_object(CtorArgs&&... ctor_args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Allocates and constructs an object of type \tcode{T}, as follows.\newline +Equivalent to: +\begin{codeblock} +T* p = allocate_object(); +try { + construct(p, std::forward(ctor_args)...); +} catch (...) { + deallocate_object(p); + throw; +} +return p; +\end{codeblock} + +\pnum +\begin{note} +\tcode{T} is not deduced and must therefore be provided as a template argument. +\end{note} +\end{itemdescr} + +\indexlibrarymember{new_object}{polymorphic_allocator}% +\begin{itemdecl} +template + void delete_object(T* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +destroy(p); +deallocate_object(p); +\end{codeblock} +\end{itemdescr} + \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} template @@ -13016,11 +13137,11 @@ monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream); monotonic_buffer_resource() - : monotonic_buffer_resource(get_default_resource()) {} + : monotonic_buffer_resource(get_default_resource()) {} explicit monotonic_buffer_resource(size_t initial_size) - : monotonic_buffer_resource(initial_size, get_default_resource()) {} + : monotonic_buffer_resource(initial_size, get_default_resource()) {} monotonic_buffer_resource(void* buffer, size_t buffer_size) - : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} + : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; @@ -13722,11 +13843,11 @@ // \ref{func.identity}, identity struct identity; - // \ref{func.not_fn}, function template \tcode{not_fn} + // \ref{func.not.fn}, function template \tcode{not_fn} template @\unspec@ not_fn(F&& f); - // \ref{func.bind_front}, function template \tcode{bind_front} - template @\unspec@ bind_front(F&&, Args&&...); + // \ref{func.bind.front}, function template \tcode{bind_front} + template @\unspec@ bind_front(F&&, Args&&...); // \ref{func.bind}, bind template struct is_bind_expression; @@ -13795,36 +13916,12 @@ namespace ranges { // \ref{range.cmp}, concept-constrained comparisons - template - requires @\seebelow@ struct equal_to; - - template - requires @\seebelow@ struct not_equal_to; - - template - requires @\seebelow@ struct greater; - - template - requires @\seebelow@ struct less; - - template - requires @\seebelow@ struct greater_equal; - - template - requires @\seebelow@ struct less_equal; - - template<> struct equal_to; - template<> struct not_equal_to; - template<> struct greater; - template<> struct less; - template<> struct greater_equal; - template<> struct less_equal; } } \end{codeblock} @@ -14450,7 +14547,7 @@ that is consistent among those specializations and is also consistent with the partial order imposed by those built-in operators. -\rSec3[comparisons.equal_to]{Class template \tcode{equal_to}} +\rSec3[comparisons.equal.to]{Class template \tcode{equal_to}} \indexlibrary{\idxcode{equal_to}}% \begin{itemdecl} @@ -14488,7 +14585,7 @@ \pnum\returns \tcode{std::forward(t) == std::forward(u)}. \end{itemdescr} -\rSec3[comparisons.not_equal_to]{Class template \tcode{not_equal_to}} +\rSec3[comparisons.not.equal.to]{Class template \tcode{not_equal_to}} \indexlibrary{\idxcode{not_equal_to}}% \begin{itemdecl} @@ -14602,7 +14699,7 @@ \pnum\returns \tcode{std::forward(t) < std::forward(u)}. \end{itemdescr} -\rSec3[comparisons.greater_equal]{Class template \tcode{greater_equal}} +\rSec3[comparisons.greater.equal]{Class template \tcode{greater_equal}} \indexlibrary{\idxcode{greater_equal}}% \begin{itemdecl} @@ -14640,7 +14737,7 @@ \pnum\returns \tcode{std::forward(t) >= std::forward(u)}. \end{itemdescr} -\rSec3[comparisons.less_equal]{Class template \tcode{less_equal}} +\rSec3[comparisons.less.equal]{Class template \tcode{less_equal}} \indexlibrary{\idxcode{less_equal}}% \begin{itemdecl} @@ -14695,97 +14792,7 @@ \indexlibrary{\idxcode{equal_to}}% \begin{itemdecl} -template - requires EqualityComparable || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, ==, const T&) struct ranges::equal_to { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return ranges::equal_to<>\{\}(x, y);} -\end{itemdescr} - -\indexlibrary{\idxcode{not_equal_to}}% -\begin{itemdecl} -template - requires EqualityComparable || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, ==, const T&) -struct ranges::not_equal_to { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return !ranges::equal_to<>\{\}(x, y);} -\end{itemdescr} - -\indexlibrary{\idxcode{greater}}% -\begin{itemdecl} -template - requires StrictTotallyOrdered || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, <, const T&) -struct ranges::greater { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return ranges::less<>\{\}(y, x);} -\end{itemdescr} - -\indexlibrary{\idxcode{less}}% -\begin{itemdecl} -template - requires StrictTotallyOrdered || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, <, const T&) -struct ranges::less { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return ranges::less<>\{\}(x, y);} -\end{itemdescr} - -\indexlibrary{\idxcode{greater_equal}}% -\begin{itemdecl} -template - requires StrictTotallyOrdered || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, <, const T&) -struct ranges::greater_equal { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return !ranges::less<>\{\}(x, y);} -\end{itemdescr} - -\indexlibrary{\idxcode{less_equal}}% -\begin{itemdecl} -template - requires StrictTotallyOrdered || Same || @\placeholdernc{BUILTIN_PTR_CMP}@(const T&, <, const T&) -struct ranges::less_equal { - constexpr bool operator()(const T& x, const T& y) const; -}; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{operator()} has effects equivalent to: -\tcode{return !ranges::less<>\{\}(y, x);} -\end{itemdescr} - -\indexlibrary{\idxcode{equal_to<>}}% -\begin{itemdecl} -template<> struct ranges::equal_to { template requires EqualityComparableWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, ==, U) constexpr bool operator()(T&& t, U&& u) const; @@ -14818,9 +14825,9 @@ \end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{not_equal_to<>}}% +\indexlibrary{\idxcode{not_equal_to}}% \begin{itemdecl} -template<> struct ranges::not_equal_to { +struct ranges::not_equal_to { template requires EqualityComparableWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, ==, U) constexpr bool operator()(T&& t, U&& u) const; @@ -14833,13 +14840,13 @@ \pnum \tcode{operator()} has effects equivalent to: \begin{codeblock} -return !ranges::equal_to<>{}(std::forward(t), std::forward(u)); +return !ranges::equal_to{}(std::forward(t), std::forward(u)); \end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{greater<>}}% +\indexlibrary{\idxcode{greater}}% \begin{itemdecl} -template<> struct ranges::greater { +struct ranges::greater { template requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(U, <, T) constexpr bool operator()(T&& t, U&& u) const; @@ -14852,13 +14859,13 @@ \pnum \tcode{operator()} has effects equivalent to: \begin{codeblock} -return ranges::less<>{}(std::forward(u), std::forward(t)); +return ranges::less{}(std::forward(u), std::forward(t)); \end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{less<>}}% +\indexlibrary{\idxcode{less}}% \begin{itemdecl} -template<> struct ranges::less { +struct ranges::less { template requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, <, U) constexpr bool operator()(T&& t, U&& u) const; @@ -14876,9 +14883,9 @@ equality-preserving\iref{concepts.equality}. For any expressions \tcode{ET} and \tcode{EU} such that \tcode{decltype((ET))} is \tcode{T} and \tcode{decltype((EU))} is \tcode{U}, exactly one of -\tcode{ranges::less<>\{\}(ET, EU)}, -\tcode{ranges::less<>\{\}(EU, ET)}, or -\tcode{ranges::equal_to<>\{\}(ET, EU)} +\tcode{ranges::less\{\}(ET, EU)}, +\tcode{ranges::less\{\}(EU, ET)}, or +\tcode{ranges::equal_to\{\}(ET, EU)} shall be \tcode{true}. \pnum @@ -14891,16 +14898,15 @@ the implementation-defined strict total order over pointers of type \tcode{P} and otherwise \tcode{false}. - \item Otherwise, equivalent to: \tcode{return std::forward(t) < std::forward(u);} \end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{greater_equal<>}}% +\indexlibrary{\idxcode{greater_equal}}% \begin{itemdecl} -template<> struct ranges::greater_equal { +struct ranges::greater_equal { template requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, <, U) constexpr bool operator()(T&& t, U&& u) const; @@ -14913,13 +14919,13 @@ \pnum \tcode{operator()} has effects equivalent to: \begin{codeblock} -return !ranges::less<>{}(std::forward(t), std::forward(u)); +return !ranges::less{}(std::forward(t), std::forward(u)); \end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{less_equal<>}}% +\indexlibrary{\idxcode{less_equal}}% \begin{itemdecl} -template<> struct ranges::less_equal { +struct ranges::less_equal { template requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(U, <, T) constexpr bool operator()(T&& t, U&& u) const; @@ -14932,7 +14938,7 @@ \pnum \tcode{operator()} has effects equivalent to: \begin{codeblock} -return !ranges::less<>{}(std::forward(u), std::forward(t)); +return !ranges::less{}(std::forward(u), std::forward(t)); \end{codeblock} \end{itemdescr} @@ -15238,7 +15244,7 @@ \end{itemdescr} -\rSec2[func.not_fn]{Function template \tcode{not_fn}} +\rSec2[func.not.fn]{Function template \tcode{not_fn}} \indexlibrary{\idxcode{not_fn}}% \begin{itemdecl} @@ -15262,11 +15268,11 @@ \pnum \mandates \tcode{is_constructible_v \&\& is_move_constructible_v} -shall be true. +is true. \pnum \expects -\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. +\tcode{FD} meets the \oldconcept{MoveConstructible} requirements. \pnum \returns @@ -15278,11 +15284,11 @@ Any exception thrown by the initialization of \tcode{fd}. \end{itemdescr} -\rSec2[func.bind_front]{Function template \tcode{bind_front}} +\rSec2[func.bind.front]{Function template \tcode{bind_front}} \indexlibrary{\idxcode{bind_front}}% \begin{itemdecl} -template +template @\unspec@ bind_front(F&& f, Args&&... args); \end{itemdecl} @@ -15313,14 +15319,14 @@ conjunction_v, is_move_constructible, is_constructible..., is_move_constructible...> \end{codeblock} -shall be true. +is true. \pnum \expects -\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. +\tcode{FD} meets the \oldconcept{MoveConstructible} requirements. For each $\tcode{T}_i$ in \tcode{BoundArgs}, if $\tcode{T}_i$ is an object type, -$\tcode{T}_i$ shall meet the requirements of \oldconcept{MoveConstructible}. +$\tcode{T}_i$ meets the \oldconcept{MoveConstructible} requirements. \pnum \returns @@ -16484,6 +16490,8 @@ template struct is_signed; template struct is_unsigned; + template struct is_bounded_array; + template struct is_unbounded_array; template struct is_constructible; template struct is_default_constructible; @@ -16621,7 +16629,7 @@ template struct invoke_result; template - using type_identity_t = typename type_identity::type; + using type_identity_t = typename type_identity::type; template // see \ref{meta.trans.other} using aligned_storage_t = typename aligned_storage::type; template @@ -16728,6 +16736,10 @@ inline constexpr bool is_signed_v = is_signed::value; template inline constexpr bool is_unsigned_v = is_unsigned::value; + template + inline constexpr bool is_bounded_array_v = is_bounded_array::value; + template + inline constexpr bool is_unbounded_array_v = is_unbounded_array::value; template inline constexpr bool is_constructible_v = is_constructible::value; template @@ -17131,6 +17143,18 @@ \tcode{T(0) < T(-1)}; otherwise, \tcode{false} & \\ \rowsep +\indexlibrary{\idxcode{is_bounded_array}}% +\tcode{template}\br + \tcode{struct is_bounded_array;} & + \tcode{T} is an array type of known bound\iref{dcl.array} + & \\ \rowsep + +\indexlibrary{\idxcode{is_unbounded_array}}% +\tcode{template}\br + \tcode{struct is_unbounded_array;} & + \tcode{T} is an array type of unknown bound\iref{dcl.array} + & \\ \rowsep + \indexlibrary{\idxcode{is_constructible}}% \tcode{template}\br \tcode{struct is_constructible;} & @@ -17652,7 +17676,7 @@ \tcode{struct is_nothrow_invocable;} & \tcode{is_invocable_v<}\br\tcode{Fn, ArgTypes...>} is \tcode{true} and the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} - is known not to throw any exceptions & + is known not to throw any exceptions\iref{expr.unary.noexcept} & \tcode{Fn} and all types in the template parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\tcode{void}, or arrays of unknown bound. \\ \rowsep @@ -17662,7 +17686,7 @@ \tcode{struct is_nothrow_invocable_r;} & \tcode{is_invocable_r_v<}\br\tcode{R, Fn, ArgTypes...>} is \tcode{true} and the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} - is known not to throw any exceptions & + is known not to throw any exceptions\iref{expr.unary.noexcept} & \tcode{Fn}, \tcode{R}, and all types in the template parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\tcode{void}, or arrays of unknown bound. \\ @@ -18064,9 +18088,10 @@ \tcode{template}\br \tcode{struct underlying_type;} & - The member typedef \tcode{type} names the underlying type - of \tcode{T}.\br - \requires{} \tcode{T} shall be a complete enumeration type\iref{dcl.enum} \\ \rowsep + If \tcode{T} is an enumeration type, the member typedef \tcode{type} names + the underlying type of \tcode{T}\iref{dcl.enum}; + otherwise, there is no member \tcode{type}.\br + \mandates \tcode{T} is not an incomplete enumeration type. \\ \rowsep \tcode{template}\br @@ -18761,8 +18786,8 @@ bool operator!=(const type_index& rhs) const noexcept; bool operator< (const type_index& rhs) const noexcept; bool operator> (const type_index& rhs) const noexcept; - bool operator<= (const type_index& rhs) const noexcept; - bool operator>= (const type_index& rhs) const noexcept; + bool operator<=(const type_index& rhs) const noexcept; + bool operator>=(const type_index& rhs) const noexcept; size_t hash_code() const noexcept; const char* name() const noexcept; @@ -18939,10 +18964,14 @@ // \ref{execpol.parunseq}, parallel and unsequenced execution policy class parallel_unsequenced_policy; + // \ref{execpol.unseq}, unsequenced execution policy + class unsequenced_policy; + // \ref{execpol.objects}, execution policy objects inline constexpr sequenced_policy seq{ @\unspec@ }; inline constexpr parallel_policy par{ @\unspec@ }; inline constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; + inline constexpr unsequenced_policy unseq{ @\unspec@ }; } \end{codeblock} @@ -19036,6 +19065,26 @@ \tcode{terminate()} shall be called. \end{itemdescr} +\rSec2[execpol.unseq]{Unsequenced execution policy} + +\indexlibrary{\idxcode{execution::unsequenced_policy}}% +\begin{itemdecl} +class execution::unsequenced_policy { @\unspec@ }; +\end{itemdecl} + +\pnum +The class \tcode{unsequenced_policy} is an execution policy type +used as a unique type to disambiguate parallel algorithm overloading and +indicate that a parallel algorithm's execution may be vectorized, +e.g., executed on a single thread using instructions +that operate on multiple data items. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::unsequenced_policy} policy, +if the invocation of an element access function exits via an uncaught exception, +\tcode{terminate()} shall be called. + \rSec2[execpol.objects]{Execution policy objects} \indexlibrary{\idxcode{seq}}% @@ -19048,6 +19097,7 @@ inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; +inline constexpr execution::unsequenced_policy execution::unseq{ @\unspec@ }; \end{itemdecl} \begin{itemdescr} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index c77de6bc85..38c0929ec5 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -198,6 +198,90 @@ \movedxref{iterator.container}{iterator.range} +% Remove underscores in stable labels. +\movedxref{alg.all_of}{alg.all.of} +\movedxref{alg.any_of}{alg.any.of} +\movedxref{alg.is_permutation}{alg.is.permutation} +\movedxref{alg.none_of}{alg.none.of} +\movedxref{any.bad_any_cast}{any.bad.any.cast} +\movedxref{char.traits.specializations.char16_t}{char.traits.specializations.char16.t} +\movedxref{char.traits.specializations.char32_t}{char.traits.specializations.char32.t} +\movedxref{char.traits.specializations.char8_t}{char.traits.specializations.char8.t} +\movedxref{class.mfct.non-static}{class.mfct.non-static} +\movedxref{comparisons.equal_to}{comparisons.equal.to} +\movedxref{comparisons.greater_equal}{comparisons.greater.equal} +\movedxref{comparisons.less_equal}{comparisons.less.equal} +\movedxref{comparisons.not_equal_to}{comparisons.not.equal.to} +\movedxref{condition_variable.syn}{condition.variable.syn} +\movedxref{depr.static_constexpr}{depr.static.constexpr} +\movedxref{forward_list.erasure}{forward.list.erasure} +\movedxref{forward_list.syn}{forward.list.syn} +\movedxref{fs.class.directory_entry}{fs.class.directory.entry} +\movedxref{fs.class.directory_iterator}{fs.class.directory.iterator} +\movedxref{fs.class.file_status}{fs.class.file.status} +\movedxref{fs.class.filesystem_error}{fs.class.filesystem.error} +\movedxref{fs.enum.file_type}{fs.enum.file.type} +\movedxref{fs.file_status.cons}{fs.file.status.cons} +\movedxref{fs.file_status.mods}{fs.file.status.mods} +\movedxref{fs.file_status.obs}{fs.file.status.obs} +\movedxref{fs.filesystem_error.members}{fs.filesystem.error.members} +\movedxref{fs.op.copy_file}{fs.op.copy.file} +\movedxref{fs.op.copy_symlink}{fs.op.copy.symlink} +\movedxref{fs.op.create_directories}{fs.op.create.directories} +\movedxref{fs.op.create_directory}{fs.op.create.directory} +\movedxref{fs.op.create_dir_symlk}{fs.op.create.dir.symlk} +\movedxref{fs.op.create_hard_lk}{fs.op.create.hard.lk} +\movedxref{fs.op.create_symlink}{fs.op.create.symlink} +\movedxref{fs.op.current_path}{fs.op.current.path} +\movedxref{fs.op.file_size}{fs.op.file.size} +\movedxref{fs.op.hard_lk_ct}{fs.op.hard.lk.ct} +\movedxref{fs.op.is_block_file}{fs.op.is.block.file} +\movedxref{fs.op.is_char_file}{fs.op.is.char.file} +\movedxref{fs.op.is_directory}{fs.op.is.directory} +\movedxref{fs.op.is_empty}{fs.op.is.empty} +\movedxref{fs.op.is_fifo}{fs.op.is.fifo} +\movedxref{fs.op.is_other}{fs.op.is.other} +\movedxref{fs.op.is_regular_file}{fs.op.is.regular.file} +\movedxref{fs.op.is_socket}{fs.op.is.socket} +\movedxref{fs.op.is_symlink}{fs.op.is.symlink} +\movedxref{fs.op.last_write_time}{fs.op.last.write.time} +\movedxref{fs.op.read_symlink}{fs.op.read.symlink} +\movedxref{fs.op.remove_all}{fs.op.remove.all} +\movedxref{fs.op.resize_file}{fs.op.resize.file} +\movedxref{fs.op.status_known}{fs.op.status.known} +\movedxref{fs.op.symlink_status}{fs.op.symlink.status} +\movedxref{fs.op.temp_dir_path}{fs.op.temp.dir.path} +\movedxref{fs.op.weakly_canonical}{fs.op.weakly.canonical} +\movedxref{func.bind_front}{func.bind.front} +\movedxref{func.not_fn}{func.not.fn} +\movedxref{futures.future_error}{futures.future.error} +\movedxref{futures.shared_future}{futures.shared.future} +\movedxref{futures.unique_future}{futures.unique.future} +\movedxref{initializer_list.syn}{initializer.list.syn} +\movedxref{optional.comp_with_t}{optional.comp.with.t} +\movedxref{sf.cmath.assoc_laguerre}{sf.cmath.assoc.laguerre} +\movedxref{sf.cmath.assoc_legendre}{sf.cmath.assoc.legendre} +\movedxref{sf.cmath.comp_ellint_1}{sf.cmath.comp.ellint.1} +\movedxref{sf.cmath.comp_ellint_2}{sf.cmath.comp.ellint.2} +\movedxref{sf.cmath.comp_ellint_3}{sf.cmath.comp.ellint.3} +\movedxref{sf.cmath.cyl_bessel_i}{sf.cmath.cyl.bessel.i} +\movedxref{sf.cmath.cyl_bessel_j}{sf.cmath.cyl.bessel.j} +\movedxref{sf.cmath.cyl_bessel_k}{sf.cmath.cyl.bessel.k} +\movedxref{sf.cmath.cyl_neumann}{sf.cmath.cyl.neumann} +\movedxref{sf.cmath.ellint_1}{sf.cmath.ellint.1} +\movedxref{sf.cmath.ellint_2}{sf.cmath.ellint.2} +\movedxref{sf.cmath.ellint_3}{sf.cmath.ellint.3} +\movedxref{sf.cmath.riemann_zeta}{sf.cmath.riemann.zeta} +\movedxref{sf.cmath.sph_bessel}{sf.cmath.sph.bessel} +\movedxref{sf.cmath.sph_legendre}{sf.cmath.sph.legendre} +\movedxref{sf.cmath.sph_neumann}{sf.cmath.sph.neumann} +\movedxref{shared_mutex.syn}{shared.mutex.syn} +\movedxref{system_error.syn}{system.error.syn} +\movedxref{time.traits.duration_values}{time.traits.duration.values} +\movedxref{time.traits.is_clock}{time.traits.is.clock} +\movedxref{time.traits.is_fp}{time.traits.is.fp} +\movedxref{utility.as_const}{utility.as.const} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)