diff --git a/papers/n4791.pdf b/papers/n4791.pdf new file mode 100644 index 0000000000..1ceb9a25d0 Binary files /dev/null and b/papers/n4791.pdf differ diff --git a/papers/n4792.html b/papers/n4792.html new file mode 100644 index 0000000000..5369176202 --- /dev/null +++ b/papers/n4792.html @@ -0,0 +1,1073 @@ +N4792 +

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

+ +

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

+ +

Acknowledgements

+ +

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

+ +

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

+ +

New papers

+ + + +

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

+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

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

+ + + +

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

+ +

CWG motion 3: P0982R1 "Weaken release sequences"

+ +

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

+ +

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

+ + + +

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

+ +

CWG motion 7 was not approved

+ +

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

+ +

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

+ +

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

+ +

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

+ +

CWG motion 12: P1353R0 "Missing feature test macros"

+ +

CWG motion 13: P1073R3 "Immediate functions"

+ +

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

+ +

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

+ +

CWG motion 16: P1094R2 "Nested inline namespaces"

+ +

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

+ +

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

+ +

Library working group motions

+ +

LWG motion 1 applies to the Concurrency TS

+ +

LWG motions 2 and 3 apply to the Library Fundamentals TS

+ +

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

+ + + +

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

+ +

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

+ + + +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

LWG motion 14: P0357R3 "reference_wrapper for incomplete types"

+ +

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

+ +

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

+ +

LWG motion 17: P1007R3 "std::assume_aligned"

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Notable editorial changes

+ +

CWG motion 11 and CWG motion 10

+ +

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

+ +

CWG motion 14

+ +

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

+ +

CWG motion 15

+ +

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

+ +

CWG motion 15 and CWG motion 4

+ +

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

+ +

LWG motion 11

+ +

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

+ +

LWG motion 13 and LWG motion 26

+ +

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

+ +

LWG motion 25

+ +

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

+ +

LWG motion 25 and CWG motion 4

+ +

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

+ +

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

+ +

After consultation with LWG, these uses have been rewritten as

+ +

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

+ +

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

+ +

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

+ +

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

+ +

with the simpler (but now equivalent)

+ +

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

+ +

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

+ +

LWG motion 26

+ +

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

+ +

Section label changes

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Minor editorial fixes

+ +

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

+ +
commit e00fef979f7c0da235351f898010658f1f074b87
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Dec 6 21:48:24 2018 -0400
+
+    [iterator.synopsis] Add reference to [alg.req.sortable]
+
+commit 9d81b4fde6dfe2b28737a79ed39f92ef9a0ee030
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Dec 2 06:07:03 2018 +0100
+
+    [view.interface] Use "inherits"/"derives" consistently.
+
+commit 358fcdc442fd620f00673081223e4313cf0af499
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 20:38:28 2018 +0100
+
+    [cpp.subst] Introduce grammar non-terminal 'va-opt-replacement'
+
+    to avoid repeated quotes of the token sequence.
+
+commit 4425a120b9a60d3c9e6aa3f1feb553082a9f1fbd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 21:37:02 2018 +0100
+
+    [iterator.concepts.readable] Turn parenthesized explanation into a note.
+
+commit de1093907b6deb7455b866d5c47a6a1a026a90a1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 22:27:20 2018 +0100
+
+    [temp.func.order] Adjust example to rules in [temp.deduct.partial].
+
+commit 07901a9f724b019c0b6634a9a0c39e5dd5208324
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 17:31:53 2018 +0100
+
+    [input.output] Avoid colons in stable labels
+
+commit 6e5dba392d19241efed299c91670cc31fcbe3826
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 7 22:05:50 2018 +0000
+
+    [template.mask.array.overview] Fix nesting of parentheses; reflow source
+
+commit 36998eae97c6876c1f67dc0425c42555dbf0cea5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 7 22:02:49 2018 +0000
+
+    [iterator.concept.iterator] Remove stray, mismatched parenthesis
+
+commit a5603f0cf1b35097a9892d9627eb03dc5cc3e154
+Author: JF Bastien <github@jfbastien.com>
+Date:   Fri Dec 7 13:48:16 2018 -0800
+
+    [basic.fundamental] Remove a footnote that was describing a particular possible manifestation of undefined behaviour
+
+    The note was problematic, as (by omission) it suggested that such behaviour might not be true for other types.
+
+commit 8035cdb6de85ff0f541b3fc78f747d060ea50ef6
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Dec 7 17:43:10 2018 -0400
+
+    [iterator.traits] Present concept requirements consistently (#2566)
+
+commit a4366dc5bf59d826a9b1aee82d317636a6239e9a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 21:51:55 2018 +0100
+
+    [iosfwd.syn] Change char_traits from 'class' to 'struct'. (#2570)
+
+commit 888da0bf8d0a07048dab8098197c7a326eda9e19
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 5 01:46:53 2018 +0000
+
+    [algorithms] Add missing closing delimiters
+
+commit 14db6ec65b7c3dbd9da2e112e09015bdcba3501f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Dec 4 23:01:27 2018 +0100
+
+    [atomics.types.operations]/20 Replace "E.g." at start of sentence with "For example,". (#2558)
+
+commit aadf7684f1e6c2fe1fa15ffa0cf2ee45b5e56cd7
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Dec 3 22:54:57 2018 +0100
+
+    [re.grammar] Add missing closing parentheses. (#2552)
+
+commit 4fc0a426f700c03aeea5b5efe040af9f3c977df8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 14:32:10 2018 +0100
+
+    [utilities] Harmonize 'For T in Types' phrasing. (#2543)
+
+    No '...' for a pack expansion should appear after 'Types', and no index on 'T'.
+
+commit 334e9f546dcb786801b9bef428f7c0fb94bee79b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 03:34:10 2018 +0100
+
+    [dcl.init] Clarify standard conversions for built-in types (#2534)
+
+commit e6cd48f407698d882a08f2bc5e3aad8ea13b495e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 03:32:38 2018 +0100
+
+    [over.best.ics] Clarify ambiguous conversion sequence (#2532)
+
+commit 89f5b1dfbabf0b5755f4e516a3be9b1e2b78ffc2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:01:21 2018 +0100
+
+    [over.ics.ref] Use 'implicit conversion sequence',
+
+    not 'standard conversion sequence' where applicable.
+
+commit af1191e9f5a0ab93214849fbfed77f75b2da673b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:48:48 2018 +0100
+
+    [class.bit] Bit-fields of sufficient width can store any value of an enumeration,
+
+    not just values of enumerators.
+
+commit 5ef7f9cbb248402f6c74f01acba87292efb0b561
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:19:14 2018 +0100
+
+    [dcl.init.aggr] Resolve grammar confusion around arrays of unknown bound
+
+commit 197db8c1fd3e57bc5c622a5e0ea9ac3f0c974e85
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 28 08:04:34 2018 +0100
+
+    [dcl.inline,dcl.align] Strike redundant 'definition'
+
+    in phrases reading 'declaration or definition',
+    because a definition is also a declaration.
+
+commit ad6385ac9730786006205d6fdca92e1d45aea13a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 23:16:26 2018 +0100
+
+    [dcl.spec] Harmonize phrasing of restrictions on decl-specifiers
+
+commit f38c14be051d91bc6492d774d45a325154b7f307
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Nov 27 23:28:09 2018 +0100
+
+    [depr.locale.category] Don't parenthesize reference after 'in'. (#2526)
+
+commit 3ba8b56c0ffa84cf8fe7bf78234fb8694d4d1498
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Nov 27 12:10:20 2018 -0800
+
+    [atomics.types.generic] Remove note that tries to encourage
+    implementations to use the same size for atomic<T> as for T.
+
+    It's not appropriate for a note to contain "should" or implementation
+    encouragement of this kind. It's also bad advice.
+
+commit e23cbb5b79397dd07c4c7adbea35b90075c78268
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Tue Nov 27 03:11:37 2018 -0500
+
+    [allocator.uses.construction] the argument name is alloc, not allocator
+
+commit 41a8baa9f739154f2b8c3f6b9e8339ede031195b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 19:21:14 2018 -0800
+
+    [unord.req] Undo change accidentally made in wrong table cell.
+
+    The intended table cell was already correctly updated.
+
+commit 9a720cd36a749057061b245772fb243678876b13
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 11 20:53:10 2018 +0200
+
+    [dcl.enum] Merge duplicate normative paragraphs on redeclarations.
+
+    Also introduce the grammar non-terminal enum-head-name
+    to simplify the description.
+
+commit 5e37f798131c38a4c609af2b8c70ce0b7a6f102f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 2 21:50:03 2018 +0200
+
+    [stmt.while] Simplify rewrite rule.
+
+commit 84d93372e79b218701611ae8599cf885fcaf13b1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 12:45:01 2018 +0100
+
+    [string.classes] Avoid special characters in stable labels
+
+    and rename [string.comparison] to [string.cmp] per convention
+
+commit 05f51e0963f8f7e9186062d97306df128ee1fdcc
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Nov 26 13:06:53 2018 -0800
+
+    [iterator.operations] Simplify distance requirements; change to expects
+
+commit 90bb6f50af1d0181a158552399739cdeaf0b6ad7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 14:09:22 2018 -0700
+
+    [iterator.operations] Simplify advance requirements; change to expects
+
+commit 12589ca08e44ad3c6c215998ccdd92af3c02ca3b
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 14:08:27 2018 -0700
+
+    [iterator.operations] advance does not decrement by a negative count
+
+commit 5f757d356d241d4fa6313f7375a275a59958358d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 18 20:20:05 2018 +0200
+
+    [dcl.init.aggr] Add example for anonymous union
+
+    initialized by a designated-initializer-list.
+
+commit b7aa3fe5f4e774edd8fe6239e707e0e0b1b44b41
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 1 10:44:12 2018 +0100
+
+    [numeric.ops] Move [numerics.defns] to the point-of-use.
+
+commit 63d15762f452fcb4787b2ca7896d9bbfde7de3ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 12:36:20 2018 +0100
+
+    [alg.find.end] and [alg.search] should not use "subsequence"
+
+commit 0f16b26b5a06b8a3cd0596ead96c54146d7e3178
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Nov 7 14:16:30 2018 -0800
+
+    [over.ics.user] Mark "user-defined conversion sequence" as a term of art
+
+commit 7e32ffd6c031771bb3a7568eb40ebe3d6b3417aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 15 19:42:52 2018 +0100
+
+    [over.best.ics] Turn 'such as' list into a note
+
+commit 915c784c12ec4570974a67e98d0086e1933d0733
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 23:42:17 2018 +0100
+
+    [iterators] Shorten labels for iterator concepts
+
+commit 3768294e5bac0fac1b40aee14c8615f6c3d2f08c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 23:35:13 2018 +0100
+
+    [iterators] Shorten stable labels for algorithm requirements
+
+commit fc0c0db579234fba09f87ee3fa7053f699066c2f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 11:59:42 2018 +0100
+
+    [ranges] Shorten and adjust stable labels
+
+commit fb5d52d59d6823d0e03b2e7ca85d76f43402efa8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:22:09 2018 +0100
+
+    [structure.summary] Add missing templated entities
+
+commit 944a64419594b455759168e089c5cd075ea848be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:33:33 2018 +0100
+
+    [func.bind_front] Use unwrap_ref_decay_t
+
+commit 12c55fcdff724855444d3e3ddfcc24ad93d9dd6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:54:46 2018 +0100
+
+    [dcl.attr.contract.check] Remove redundant statement that violation handler is implementation-defined
+
+commit ae11d65ac5df8a7e605f07bc1d36ed584002fd15
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 14:01:32 2018 +0100
+
+    [expr] Fix cross-references for 'composite pointer type'
+
+    to refer to [expr.type], not [expr.prop].
+
+commit 42f956e7e80a4dfd81608b366e4f7813332d7dc0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 18:31:42 2018 +0100
+
+    [temp] Use 'deduced as' instead of 'deduced to'
+
+    in comments explaining examples
+
+commit 602a81d2d88ec98fef3d4feeaf5b24079e1e2110
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Oct 12 17:35:23 2018 +0800
+
+    [class.mem] Add opaque-enum-declaration to member-declaration
+
+commit 8ddcba4252b4a45194b8fdf4ebd2a439cb5e5147
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Tue Oct 30 08:58:23 2018 +0900
+
+    [conv.lval] Improve a bit more the note about std::nullptr_t case
+
+    - "read the object" -> "access the object"
+      The "read" was derived from the rule at [intro.execution], but it
+      didn't fit well here.
+    - "the object" -> "the object to which the glvalue refers"
+      Make it clear what "the object" refers to.
+
+    https://github.com/cplusplus/draft/pull/2372#pullrequestreview-169248002
+
+commit 0b35a4688d09a385488f0d23c296afa622d7b02e
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Thu Oct 25 02:59:31 2018 +0900
+
+    [conv.lval] Improve the note about std::nullptr_t case
+
+    The meaning of "fetched from memory" is vague, and the two uses of term
+    "access" [defns.access] are inappropreate here because
+      - it causes undefined behavior to access an inactive member of a
+        union, based on the rule of out-of-lifetime object [basic.life]:
+        > The program has undefined behavior if:
+        >   - the glvalue is used to access the object, or
+      - it implies reading the referenced object of std::nullptr_t,
+        which is defined to be a side effect for volatile-qualified case.
+        [intro.execution]
+        > Reading an object designated by a volatile glvalue, ... are all
+        > side effects, ...
+
+commit a694c9131618fd71b65faa8022cd6210dfa760f7
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Nov 11 21:31:03 2018 +0100
+
+    [expr.static.cast] Say 'lvalue denoting ...' instead of 'lvalue to ...'
+
+commit 2e054057e5a0db3e5563dd05286b04b55c3a3b87
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 21 12:02:41 2018 +0100
+
+    [basic.stc.dynamic.allocation] Fix cross-reference for get_new_handler
+
+commit d4439240b74cf044bc7626ed364eeba291ca79dd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 21:06:30 2018 +0200
+
+    [basic.type.qualifier] Clarify the definitions of const/volatile object
+
+commit d348800a5b0c2e594cf5e0b6e22404d52731e263
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 11 09:47:10 2018 +0200
+
+    [dcl.spec.auto] Return type deduction should refer to templated entity
+
+commit 2aa12aea978a0a79b725ce7552a1803c282a1c93
+Author: Géry Ogam <gery.ogam@gmail.com>
+Date:   Mon Nov 26 10:28:28 2018 +0100
+
+    [basic.lval] Correct an article in the prvalue definition
+
+    An operator can have multiple operands.
+
+commit e63542071ba4acee0adb82bd1221fdb0158a4eef
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Nov 17 16:29:38 2018 -0800
+
+    [cmp.categories,time.cal] Change "explicit constexpr" to "constexpr explicit"
+
+    Per discussion in #2371.
+
+commit e6bbbbf62cddcbc6cea43a7589cfbcc48817b74b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 00:27:52 2018 -0800
+
+    [unord.req] Clarify what r1 is and remove unnecessary variable e.
+
+commit 38f9dccc5abe1d53e28249bd09be79a25d9b2427
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Nov 16 02:27:56 2018 -0800
+
+    [unord.req] Use bullets for the list of denoting variables.
+
+commit e6b8936788decfb6c29ea527f1195ec3679a1195
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 00:17:04 2018 -0800
+
+    [func.def] Simplify "references to functions and references to objects"
+    to simply "references".
+
+commit dafbb9445f11ad231abbf72028c29b6dd77c9334
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 19 09:44:01 2018 +0100
+
+    [func.not_fn,func.bind_front] Some clarifications
+
+    'a target object' -> 'the target object'
+    render 'initializer' as a grammar term and add a cross-reference
+    to dcl.init
+    add cross-references to expr.call
+
+commit 40fc57e9efdf5159a981cd87c9d8d765fd3f29ae
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 23:11:27 2018 -0800
+
+    [iterators] Remove bogus "shall"s is "Expects" elements.
+
+commit 9110f52c0e9550472b55845ba1c063333a94ad17
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 21:46:09 2018 -0800
+
+    [range] [iterators] Replace uses of { I } -> Same<T>& requirement.
+
+    This form of requirement was made ill-formed by P1084R2. In its place,
+    use { I } -> Same<T&>, after discussion on the lib reflector.
+
+commit 00da6c53f744a1781a1ce23cd3026af9d87f1f8a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 21:42:11 2018 -0800
+
+    [incrementable.traits] [readable.traits] Remove redundant remove_const_t
+    on type that cannot be const-qualified.
+
+commit e57b65067a5c73e20f2287b0ca0782d5d7d0333a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 22:20:47 2018 -0800
+
+    [std.iterator.tags] Replace "the most specific category tag" with "a
+    category tag".
+
+    The new text was present in the Ranges wording, but with no insertion /
+    deletion markup to indicate that an edit was to be performed. However,
+    consultation with LWG revealed that this was an intentional edit missing
+    markup.
+
+commit 92326665186c9c4e29f058f5b8d0ae5ea9814465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 17 15:29:01 2018 +0100
+
+    [pairs.spec,tuple.creation] Simplify description
+
+    by inlining unwrap_ref_decay_t into its point of use.
+
+commit d9521a91ab07548e888bd5be386822c0148a111f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 18:44:37 2018 -0800
+
+    [iostream.forward.overview] Convert incomplete wording with no normative
+    effect to an example.
+
+commit 6260a047c0f3120a0570e6418f201294e6442664
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Nov 22 23:58:55 2018 -0800
+
+    [diff.cpp17.input.output] Add ill-formed comment and a still well-formed use.
+
+commit a0a637a0b2797b2809982836c9330052a8465172
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 01:29:58 2018 -0800
+
+    [expr.prim.req.compound] Replace note that restates what
+    'immediately-declared constraint' means with an example.
+
+commit 27797625e16a95b8946a353b09a86544c411ce61
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 01:08:30 2018 -0800
+
+    [temp.param] Remove unused grammar production default-template-argument.
+
+commit 9b525539f0c7bf734be8e01db082fca775dbd028
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 00:52:55 2018 -0800
+
+    [dcl.type.simple] Factor out decltype(e) wording into its own subclause.
+
+commit 4cc61d46edce136f5dfaeeee671ea58039b032e2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 19:55:37 2018 -0800
+
+    [expr.prim.req.compound] Resolve conflict between P1084R2 and P1141R2.
+
+    Replace /qualified-concept-name/ with /type-constraint/ in grammar
+    for /return-type-requirement/, and rewrite the new bullet for
+    /return-type-requirement/ added in P1084R2 to use the term
+    immediately-declared constraint introduced in P1141R2.
+
+commit d4d65994bcf692c472cee2ed83db34e4c94266e6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:40:25 2018 -0800
+
+    [expr.const] Remove redundant bullet from definition of manifestly
+    constant-evaluated. Constexpr variables are always usable in constant
+    expressions.
+
+commit e201f3325d8a91319c37a702e50d8032759fd822
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:37:02 2018 -0800
+
+    [expr.const] Factor out some commonality from 'manifestly
+    constant-evaluated' and 'potentially constant evaluated'.
+
+commit e58439bce8af85e6569328272c2cfb73f5fc44d6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:13:58 2018 -0800
+
+    [expr.const] Add missing definition of 'usable in constant expressions'
+    for (sub)objects and reference members.
+
+commit b4eec9d65bcd54430c02ac7e66c88e63360801e6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 14 23:45:01 2018 +0100
+
+    [c.mb.wcs] The parameter is called 's', not 'buf'
+
+commit f892418bf423d6495beaf75093db3dd97aff2d14
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 21:26:05 2018 -0800
+
+    [gram] Remove now-incorrect claim that a typedef-name naming a class is
+    a class-name.
+
+commit 8b70fdad014640772691057ada5b528bc8724b12
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 12 03:10:20 2018 +0100
+
+    [expr,class,temp] Remove vestigious references
+
+    to pseudo-destructor-name and the removed section [expr.pseudo].
+
+    Add xrefdelta entry for removed section.
+
+commit fb22bbd60aba1f3aaf9288ab08a7feeb8e4c0101
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 19:51:28 2018 -0800
+
+    [expr.prim.req.compound] Change "is" to "has a" when refering to grammar terms.
+
+commit 9bcfe7de3dd5bd4ad429011e169fca583bfa30b0
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Nov 20 23:16:11 2018 +0100
+
+    [dcl.fct] Add missing period after last sentence in example. (#2494)
+
+commit 12935b8549c0412f528b33b7795a19cda7ae8dd6
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Nov 6 02:03:15 2018 -0500
+
+    [class.copy.assign] Use Oxford comma.
+
+    Also convert some text font spaces into tcode spaces.
+
+commit 9437d29c92b8c2e4e779acaa2677e2cbb8800414
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 6 03:37:18 2018 +0100
+
+    [thread] Remove class name repeated in subheadings (#2368)
+
+commit 8ae6a8fbd5e0b19e0c2fad3598c3693b72081606
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 6 03:36:58 2018 +0100
+
+    [input.output] Remove class name repeated in subheadings (#2366)
+
+commit 96028f0000bbe2709bcdefe0fe3edc24862529a7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 31 04:21:52 2018 -0700
+
+    [iterator.requirements.general] Operations satisfy requirements, not operations (#2375)
+
+    Drive-by: change "satisfy .... requirements" to "meet ... requirements".
+
+commit a43c2b30d71827325d8fdfbbd1488c570993adb7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 19 15:17:52 2018 +0200
+
+    [localization] Remove class name repeated in subheadings (#2364)
+
+commit 9405969f396d371284945904b534bd3f3e029d47
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 18 20:39:54 2018 +0200
+
+    [numerics] Remove class name repeated in subheadings (#2362)
+
+commit 4afc80a9ab5b78cb3c1fe70495e162d40f427116
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 02:19:26 2018 -0700
+
+    [output.iterators] Remove misleading italics from note (#2360)
+
+    Since LWG asked me to remove these from P0896's OutputIterator, they probably don't belong in Cpp17OutputIterator either.
+
+commit 853f6bfc029f4d290c8a31da14f4282ee298cdc5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 15 16:10:00 2018 +0200
+
+    [iterators] Remove class name repeated in subheadings (#2358)
+
+commit 3a6d922f5ef5c3c77cfe74e39563879698716768
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 13 15:07:28 2018 +0200
+
+    [re] Remove class name repeated in subheadings (#2356)
+
+commit d0bb9916b779f6b113294ce9387063cad2f4b465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 13 10:45:05 2018 +0200
+
+    [utilities] Remove class name repeated in subheadings (#2355)
+
+commit 506ec70eab720e757555be0059c5371ff4117fba
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 10 23:35:18 2018 +0200
+
+    [class.this] Turn redundant statement on cv-qualified constructors/destructors
+    into a note.
+
+commit 7c0e7fd6396d5509027c390d9557f9642d30db42
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Oct 10 15:06:10 2018 +0100
+
+    [cpp.cond] Fix "carries_depencency" typo in table
+
+commit e8fee95850cc5a68ea09fb29f4e50c28632ed348
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 23:24:28 2018 +0200
+
+    [basic.types] Clarify that 'value representation' does not depend on the value. (#2246)
+
diff --git a/papers/n4792.md b/papers/n4792.md new file mode 100644 index 0000000000..381bc6c844 --- /dev/null +++ b/papers/n4792.md @@ -0,0 +1,939 @@ +# N4792 Editors' Report -- Programming Languages -- C++ + +2018-12-07 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Casey Carter +and Tim Song +for supplying the LaTeX sources for +[P0896R4](http://wg21.link/p0896r4) (LWG motion 25, 208 pages of wording changes) +and +[P1148R0](http://wg21.link/p1148r0) (LWG motion 12, 55 pages of wording changes), +respectively, +and to Tony Van Eerd +for supplying a pull request for +[P1085R2](http://wg21.link/p1085r2) (LWG motion 23). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4791](http://wg21.link/n4791) is the current working draft for C++20. It replaces [N4778](http://wg21.link/n4778). + * N4792 is this Editors' Report. + +Papers N4788 and N4789 (earlier versions of the post-San-Diego Working Draft +and Editors' Report) are withdrawn and replaced by the above papers due to an +administrative hiccup. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1350r0) for 3 issues in "tentatively ready" status applied, resolving 4 issues: + + * [1636](http://wg21.link/cwg1636) Bits required for negative enumerator values **superseded by CWG Motion 10** + * [1781](http://wg21.link/cwg1781) Converting from `nullptr_t` to `bool` in overload resolution + * [2133](http://wg21.link/cwg2133) Converting `std::nullptr_t` to `bool` **resolved by resolution to CWG1781** + * [2373](http://wg21.link/cwg2373) Incorrect handling of static member function templates in partial ordering + +CWG motion 2: [P0668R5 "Revising the C++ memory model"](http://wg21.link/p0668r5) + +CWG motion 3: [P0982R1 "Weaken release sequences"](http://wg21.link/p0982r1) + +CWG motion 4: [P1084R2 "Today's *return-type-requirement*s are insufficient"](http://wg21.link/p1084r2) **see below** + +CWG motion 5: [P1131R2 "*simple-template-id* is ambiguous between *class-name* and *type-name*"](http://wg21.link/p1131r2), resolving 1 core issue: + + * [2292](http://wg21.link/cwg2292) *simple-template-id* is ambiguous between *class-name* and *type-name* + +CWG motion 6: [P1289R1 "Access control in contract conditions"](http://wg21.link/p1289r1) + +CWG motion 7 was not approved + +CWG motion 8: [P1002R1 "`try`-`catch` blocks in `constexpr` functions"](http://wg21.link/p1002r1) + +CWG motion 9: [P1327R1 "Allowing `dynamic_cast`, polymorphic `typeid` in constant expressions"](http://wg21.link/p1327r1) + +CWG motion 10: [P1236R1 "Signed integers are two's complement"](http://wg21.link/p1236r1) (wording for [P0907R4](http://wg21.link/p0907r4)) + +CWG motion 11: [P0482R6 "`char8_t`: a type for UTF-8 characters and strings"](http://wg21.link/p0482r6) **see below** + +CWG motion 12: [P1353R0 "Missing feature test macros"](http://wg21.link/p1353r0) + +CWG motion 13: [P1073R3 "Immediate functions"](http://wg21.link/p1073r3) + +CWG motion 14: [P0595R2 "`std::is_constant_evaluated()`"](http://wg21.link/p0595r2) **see below** + +CWG motion 15: [P1141R2 "Yet another approach for constrained declarations"](http://wg21.link/p1141r2) **see below** + +CWG motion 16: [P1094R2 "Nested inline namespaces"](http://wg21.link/p1094r2) + +CWG motion 17: [P1330R0 "Changing the active member of a union inside `constexpr`"](http://wg21.link/p1330r0) + +Core motions added a total of 1 page to Clause 1-14. + +### Library working group motions + +LWG motion 1 applies to the Concurrency TS + +LWG motions 2 and 3 apply to the Library Fundamentals TS + +LWG motion 4: [Library issue resolutions](http://wg21.link/p1224r0) for 9 issues in "Ready" status and 23 issues in "Tentatively Ready" status applied: + + * [2183](http://wg21.link/lwg2183) Muddled allocator requirements for `match_results` constructors + * [2184](http://wg21.link/lwg2184) Muddled allocator requirements for `match_results` assignments + * [2412](http://wg21.link/lwg2412) `promise::set_value()` and `promise::get_future()` should not race + * [2682](http://wg21.link/lwg2682) `filesystem::copy()` won't create a symlink to a directory + * [2936](http://wg21.link/lwg2936) Path comparison is defined in terms of the generic format + * [2943](http://wg21.link/lwg2943) Problematic specification of the wide version of `basic_filebuf::open` + * [2995](http://wg21.link/lwg2995) `basic_stringbuf` default constructor forbids it from using SSO capacity + * [2996](http://wg21.link/lwg2996) Missing rvalue overloads for `shared_ptr` operations + * [3008](http://wg21.link/lwg3008) `make_shared` (sub)object destruction semantics are not specified + * [3025](http://wg21.link/lwg3025) Map-like container deduction guides should use `pair`, not `pair` + * [3031](http://wg21.link/lwg3031) Algorithms and predicates with non-const reference arguments + * [3037](http://wg21.link/lwg3037) `polymorphic_allocator` and incomplete types + * [3038](http://wg21.link/lwg3038) `polymorphic_allocator::allocate` should not allow integer overflow to create vulnerabilities + * [3054](http://wg21.link/lwg3054) `uninitialized_copy` appears to not be able to meet its exception-safety guarantee + * [3065](http://wg21.link/lwg3065) [LWG 2989](http://wg21.link/lwg2989) missed that all `path`'s other operators should be hidden friends as well + * [3096](http://wg21.link/lwg3096) `path::lexically_relative` is confused by trailing slashes + * [3116](http://wg21.link/lwg3116) *OUTERMOST_ALLOC_TRAITS* needs `remove_reference_t` + * [3122](http://wg21.link/lwg3122) `__cpp_lib_chrono_udls` was accidentally dropped + * [3127](http://wg21.link/lwg3127) `basic_osyncstream::rdbuf` needs a `const_cast` + * [3128](http://wg21.link/lwg3128) `strstream::rdbuf` needs a `const_cast` + * [3129](http://wg21.link/lwg3129) `regex_token_iterator` constructor uses wrong pointer arithmetic + * [3130](http://wg21.link/lwg3130) [input.output] needs many `addressof` + * [3131](http://wg21.link/lwg3131) `addressof` all the things + * [3132](http://wg21.link/lwg3132) Library needs to ban macros named `expects` or `ensures` + * [3137](http://wg21.link/lwg3137) Header for `__cpp_lib_to_chars` + * [3140](http://wg21.link/lwg3140) *COMMON_REF* is unimplementable as specified + * [3145](http://wg21.link/lwg3145) `file_clock` breaks ABI for C++17 implementations + * [3147](http://wg21.link/lwg3147) Definitions of `likely` and `unlikely` are likely to cause problems + * [3148](http://wg21.link/lwg3148) `` should be freestanding + * [3153](http://wg21.link/lwg3153) `Common` and `common_type` have too little in common + * [3154](http://wg21.link/lwg3154) `Common` and `CommonReference` have a common defect + * [3160](http://wg21.link/lwg3160) `atomic_ref() = delete;` should be deleted + +LWG motion 5: [P1123R0 "Editorial guidance for merging P0019R8 and P0528R3"](http://wg21.link/p1123r0) (see [P0019R8](http://wg21.link/p0019r8), [P0528R3](http://wg21.link/p0528r3)) + +LWG motion 6: [P0487R1 "Fixing `operator>>(basic_istream&, CharT*)`"](http://wg21.link/p0487r1), resolving 1 library issue: + + * [2499](http://wg21.link/lwg2499) `operator>>(basic_istream&, CharT*)` makes it hard to avoid buffer overflows + +LWG motion 7: [P0602R4 "`variant` and `optional` should propagate copy/move triviality"](http://wg21.link/p0602r4) + +LWG motion 8: [P0655R1 "`visit`: explicit return type for `visit`"](http://wg21.link/p0655r1) + +LWG motion 9: [P0972R0 "`` `zero()`, `min()`, and `max()` should be `noexcept`"](http://wg21.link/p0972r0) + +LWG motion 10: [P1006R1 "`constexpr` in `std::pointer_traits`"](http://wg21.link/p1006r1) + +LWG motion 11: [P1032R1 "Miscellaneous `constexpr` bits"](http://wg21.link/p1032r1) **see below** + +LWG motion 12: [P1148R0 "Cleaning up clause 20 (strings)"](http://wg21.link/p1148r0) + +LWG motion 13: [P0318R1 "`unwrap_ref_decay` and `unwrap_reference`"](http://wg21.link/p0318r1) **see below** + +LWG motion 14: [P0357R3 "`reference_wrapper` for incomplete types"](http://wg21.link/p0357r3) + +LWG motion 15: [P0608R3 "A sane `variant` converting constructor"](http://wg21.link/p0608r3) + +LWG motion 16: [P0771R1 "`std::function` move constructor should be `noexcept`"](http://wg21.link/p0771r1) + +LWG motion 17: [P1007R3 "`std::assume_aligned`"](http://wg21.link/p1007r3) + +LWG motion 18: [P1020R1 "Smart pointer creation with default initialization"](http://wg21.link/p1020r1) + +LWG motion 19: [P1285R0 "Improving completeness requirements for type traits"](http://wg21.link/p1285r0) + +LWG motion 20: [P1248R1 "Remove `CommonReference` requirement from `StrictWeakOrdering`"](http://wg21.link/p1248r1) + +LWG motion 21: [P0591R4 "Utility functions to implement uses-allocator construction"](http://wg21.link/p0591r4) + +LWG motion 22: [P0899R1 "LWG 3016 is not a defect"](http://wg21.link/p0899r1) (see [LWG 3016](http://wg21.link/lwg3016)) + +LWG motion 23: [P1085R2 "Should `span` be regular?"](http://wg21.link/p1085r2) + +LWG motion 24: [P1165R1 "Make stateful allocator propagation more consistent for `operator+(basic_string)`"](http://wg21.link/p1165r1) + +LWG motion 25: [P0896R4 "The One Ranges proposal"](http://wg21.link/p0896r4) **see below** + +LWG motion 26: [P0356R5 "Simplified partial function application"](http://wg21.link/p0356r5) **see below** + +LWG motion 27: [P0919R3 "Heterogeneous lookup for unordered containers"](http://wg21.link/p0919r3) + +LWG motion 28: [P1209R0 "Adopt consistent container erasure from Library Fundamentals 2"](http://wg21.link/p1209r0) + +Library motions added a total of 133 pages (and 1 Clause) to Clause 15-31. + +## Notable editorial changes + +### CWG motion 11 and CWG motion 10 + +Rebased `char8_t` wording on the revised description of fundamental types +introduced by CWG motion 10. The description of `unsigned char` as the +underlying type of `char8_t` now renders unnecessary some of the other +wording in CWG motion 11; such wording has consequently not been applied. + +### CWG motion 14 + +After consulting with CWG, added the missing definition for "usable in constant +expressions" as applied to objects and references. + +### CWG motion 15 + +Removed now-unused grammar production *default-template-argument*. + +### CWG motion 15 and CWG motion 4 + +CWG motion 4 adds new uses of the grammar production *qualified-concept-name* +that CWG motion 15 removes. These have been updated to instead refer to the +new production *type-constraint*, and the normative wording of CWG motion 4 +has been rewritten to use the new term "immediately-declared constraint", +both of which were introduced by CWG motion 15. + +### LWG motion 11 + +Change 10 included an editing instruction to make matching changes elsewhere +in the draft. There does not appear to be any "elsewhere" to make said changes. +This editing instruction was ignored. + +### LWG motion 13 and LWG motion 26 + +The specification of `bind_front` was simplified by replacing *DECAY_UNWRAP* +a use of the new `unwrap_ref_decay_t` alias template introduced by LWG motion 13. + +### LWG motion 25 + +The wording paper contained an unmarked modification of [std.iterator.tags], +replacing "the most specific category tag" with "a category tag". +After consulting with the paper authors, the change was intentional, and +the corresponding edit has been applied despite not being marked up. + +### LWG motion 25 and CWG motion 4 + +CWG motion 4 removes a grammar production from *requires-clause*s, but +LWG motion 25 adds new uses of said grammar production. Those uses are all +of the form + +``` +requires { + { expr } -> Same&; +} +``` + +After consultation with LWG, these uses have been rewritten as + +``` +requires { + { expr } -> Same; +} +``` + +which is believed to both correctly reflect the intent and not change the +meaning in practice of any of the uses introduced by LWG motion 25. + +Additionally, CWG motion 4 contains an instruction to replace all constructs +of the form + +``` +requires { + E; requires Concept; +} +``` + +with the simpler (but now equivalent) + +``` +requires { + { E } -> Concept; +} +``` + +throughout [concepts]. However, LWG motion 25 adds many more instances of +the former pattern throughout several other clauses. All such instances +throughout the working draft have been replaced. + +### LWG motion 26 + +A feature test macro name `__cpp_lib_bind_front` was recommended by the paper, +but no wording changes were included to add said feature test macro to the +working draft's table of feature test macros. The macro has been added to +the table anyway. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, the following changes have been made: + +[string.op+=] has been renamed to [string.op.append]. +[string.op+] has been renamed to [string.op.plus]. + +[re.regex.nmswap] was the only subclause in its parent [re.regex.nonmemb]. +The former heading has been removed, leaving the old content directly in +[re.regex.nonmemb]. + +[istream::sentry], +[ostream::sentry], +[ios::failure], +[ios::fmtflatgs], +[ios::iostate], +[ios::openmode], +[ios::seekdir], and +[ios::Init] +have been renamed, replacing the "::" with a "." +and converting "Init" to lowercase. + +See the appendix "Cross-references from ISO C++ 2017" in the working draft +for a full list of sectoin label changes since C++17. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4778 is below. +This list excludes changes +that do not affect the body text or only affect whitespace or typeface. For a +complete list including such changes (or for the actual deltas applied by these +changes), consult the [draft sources on github](https://github.com/cplusplus/draft/compare/n4778...n4791). + + commit e00fef979f7c0da235351f898010658f1f074b87 + Author: Johel Ernesto Guerrero Peña + Date: Thu Dec 6 21:48:24 2018 -0400 + + [iterator.synopsis] Add reference to [alg.req.sortable] + + commit 9d81b4fde6dfe2b28737a79ed39f92ef9a0ee030 + Author: Eelis van der Weegen + Date: Sun Dec 2 06:07:03 2018 +0100 + + [view.interface] Use "inherits"/"derives" consistently. + + commit 358fcdc442fd620f00673081223e4313cf0af499 + Author: Jens Maurer + Date: Tue Nov 27 20:38:28 2018 +0100 + + [cpp.subst] Introduce grammar non-terminal 'va-opt-replacement' + + to avoid repeated quotes of the token sequence. + + commit 4425a120b9a60d3c9e6aa3f1feb553082a9f1fbd + Author: Jens Maurer + Date: Fri Dec 7 21:37:02 2018 +0100 + + [iterator.concepts.readable] Turn parenthesized explanation into a note. + + commit de1093907b6deb7455b866d5c47a6a1a026a90a1 + Author: Jens Maurer + Date: Fri Dec 7 22:27:20 2018 +0100 + + [temp.func.order] Adjust example to rules in [temp.deduct.partial]. + + commit 07901a9f724b019c0b6634a9a0c39e5dd5208324 + Author: Jens Maurer + Date: Sat Dec 1 17:31:53 2018 +0100 + + [input.output] Avoid colons in stable labels + + commit 6e5dba392d19241efed299c91670cc31fcbe3826 + Author: Thomas Köppe + Date: Fri Dec 7 22:05:50 2018 +0000 + + [template.mask.array.overview] Fix nesting of parentheses; reflow source + + commit 36998eae97c6876c1f67dc0425c42555dbf0cea5 + Author: Thomas Köppe + Date: Fri Dec 7 22:02:49 2018 +0000 + + [iterator.concept.iterator] Remove stray, mismatched parenthesis + + commit a5603f0cf1b35097a9892d9627eb03dc5cc3e154 + Author: JF Bastien + Date: Fri Dec 7 13:48:16 2018 -0800 + + [basic.fundamental] Remove a footnote that was describing a particular possible manifestation of undefined behaviour + + The note was problematic, as (by omission) it suggested that such behaviour might not be true for other types. + + commit 8035cdb6de85ff0f541b3fc78f747d060ea50ef6 + Author: Johel Ernesto Guerrero Peña + Date: Fri Dec 7 17:43:10 2018 -0400 + + [iterator.traits] Present concept requirements consistently (#2566) + + commit a4366dc5bf59d826a9b1aee82d317636a6239e9a + Author: Jens Maurer + Date: Fri Dec 7 21:51:55 2018 +0100 + + [iosfwd.syn] Change char_traits from 'class' to 'struct'. (#2570) + + commit 888da0bf8d0a07048dab8098197c7a326eda9e19 + Author: Thomas Köppe + Date: Wed Dec 5 01:46:53 2018 +0000 + + [algorithms] Add missing closing delimiters + + commit 14db6ec65b7c3dbd9da2e112e09015bdcba3501f + Author: Eelis + Date: Tue Dec 4 23:01:27 2018 +0100 + + [atomics.types.operations]/20 Replace "E.g." at start of sentence with "For example,". (#2558) + + commit aadf7684f1e6c2fe1fa15ffa0cf2ee45b5e56cd7 + Author: Eelis + Date: Mon Dec 3 22:54:57 2018 +0100 + + [re.grammar] Add missing closing parentheses. (#2552) + + commit 4fc0a426f700c03aeea5b5efe040af9f3c977df8 + Author: Jens Maurer + Date: Sat Dec 1 14:32:10 2018 +0100 + + [utilities] Harmonize 'For T in Types' phrasing. (#2543) + + No '...' for a pack expansion should appear after 'Types', and no index on 'T'. + + commit 334e9f546dcb786801b9bef428f7c0fb94bee79b + Author: Jens Maurer + Date: Sat Dec 1 03:34:10 2018 +0100 + + [dcl.init] Clarify standard conversions for built-in types (#2534) + + commit e6cd48f407698d882a08f2bc5e3aad8ea13b495e + Author: Jens Maurer + Date: Sat Dec 1 03:32:38 2018 +0100 + + [over.best.ics] Clarify ambiguous conversion sequence (#2532) + + commit 89f5b1dfbabf0b5755f4e516a3be9b1e2b78ffc2 + Author: Jens Maurer + Date: Tue Nov 27 22:01:21 2018 +0100 + + [over.ics.ref] Use 'implicit conversion sequence', + + not 'standard conversion sequence' where applicable. + + commit af1191e9f5a0ab93214849fbfed77f75b2da673b + Author: Jens Maurer + Date: Tue Nov 27 22:48:48 2018 +0100 + + [class.bit] Bit-fields of sufficient width can store any value of an enumeration, + + not just values of enumerators. + + commit 5ef7f9cbb248402f6c74f01acba87292efb0b561 + Author: Jens Maurer + Date: Tue Nov 27 22:19:14 2018 +0100 + + [dcl.init.aggr] Resolve grammar confusion around arrays of unknown bound + + commit 197db8c1fd3e57bc5c622a5e0ea9ac3f0c974e85 + Author: Jens Maurer + Date: Wed Nov 28 08:04:34 2018 +0100 + + [dcl.inline,dcl.align] Strike redundant 'definition' + + in phrases reading 'declaration or definition', + because a definition is also a declaration. + + commit ad6385ac9730786006205d6fdca92e1d45aea13a + Author: Jens Maurer + Date: Tue Nov 27 23:16:26 2018 +0100 + + [dcl.spec] Harmonize phrasing of restrictions on decl-specifiers + + commit f38c14be051d91bc6492d774d45a325154b7f307 + Author: Eelis + Date: Tue Nov 27 23:28:09 2018 +0100 + + [depr.locale.category] Don't parenthesize reference after 'in'. (#2526) + + commit 3ba8b56c0ffa84cf8fe7bf78234fb8694d4d1498 + Author: Richard Smith + Date: Tue Nov 27 12:10:20 2018 -0800 + + [atomics.types.generic] Remove note that tries to encourage + implementations to use the same size for atomic as for T. + + It's not appropriate for a note to contain "should" or implementation + encouragement of this kind. It's also bad advice. + + commit e23cbb5b79397dd07c4c7adbea35b90075c78268 + Author: Sergey Zubkov + Date: Tue Nov 27 03:11:37 2018 -0500 + + [allocator.uses.construction] the argument name is alloc, not allocator + + commit 41a8baa9f739154f2b8c3f6b9e8339ede031195b + Author: Richard Smith + Date: Mon Nov 26 19:21:14 2018 -0800 + + [unord.req] Undo change accidentally made in wrong table cell. + + The intended table cell was already correctly updated. + + commit 9a720cd36a749057061b245772fb243678876b13 + Author: Jens Maurer + Date: Thu Oct 11 20:53:10 2018 +0200 + + [dcl.enum] Merge duplicate normative paragraphs on redeclarations. + + Also introduce the grammar non-terminal enum-head-name + to simplify the description. + + commit 5e37f798131c38a4c609af2b8c70ce0b7a6f102f + Author: Jens Maurer + Date: Mon Apr 2 21:50:03 2018 +0200 + + [stmt.while] Simplify rewrite rule. + + commit 84d93372e79b218701611ae8599cf885fcaf13b1 + Author: Jens Maurer + Date: Mon Nov 26 12:45:01 2018 +0100 + + [string.classes] Avoid special characters in stable labels + + and rename [string.comparison] to [string.cmp] per convention + + commit 05f51e0963f8f7e9186062d97306df128ee1fdcc + Author: Casey Carter + Date: Mon Nov 26 13:06:53 2018 -0800 + + [iterator.operations] Simplify distance requirements; change to expects + + commit 90bb6f50af1d0181a158552399739cdeaf0b6ad7 + Author: Casey Carter + Date: Wed Oct 17 14:09:22 2018 -0700 + + [iterator.operations] Simplify advance requirements; change to expects + + commit 12589ca08e44ad3c6c215998ccdd92af3c02ca3b + Author: Casey Carter + Date: Wed Oct 17 14:08:27 2018 -0700 + + [iterator.operations] advance does not decrement by a negative count + + commit 5f757d356d241d4fa6313f7375a275a59958358d + Author: Jens Maurer + Date: Thu Oct 18 20:20:05 2018 +0200 + + [dcl.init.aggr] Add example for anonymous union + + initialized by a designated-initializer-list. + + commit b7aa3fe5f4e774edd8fe6239e707e0e0b1b44b41 + Author: Jens Maurer + Date: Thu Nov 1 10:44:12 2018 +0100 + + [numeric.ops] Move [numerics.defns] to the point-of-use. + + commit 63d15762f452fcb4787b2ca7896d9bbfde7de3ad + Author: Jens Maurer + Date: Mon Nov 26 12:36:20 2018 +0100 + + [alg.find.end] and [alg.search] should not use "subsequence" + + commit 0f16b26b5a06b8a3cd0596ead96c54146d7e3178 + Author: Casey Carter + Date: Wed Nov 7 14:16:30 2018 -0800 + + [over.ics.user] Mark "user-defined conversion sequence" as a term of art + + commit 7e32ffd6c031771bb3a7568eb40ebe3d6b3417aa + Author: Jens Maurer + Date: Thu Nov 15 19:42:52 2018 +0100 + + [over.best.ics] Turn 'such as' list into a note + + commit 915c784c12ec4570974a67e98d0086e1933d0733 + Author: Jens Maurer + Date: Mon Nov 26 23:42:17 2018 +0100 + + [iterators] Shorten labels for iterator concepts + + commit 3768294e5bac0fac1b40aee14c8615f6c3d2f08c + Author: Jens Maurer + Date: Mon Nov 26 23:35:13 2018 +0100 + + [iterators] Shorten stable labels for algorithm requirements + + commit fc0c0db579234fba09f87ee3fa7053f699066c2f + Author: Jens Maurer + Date: Mon Nov 26 11:59:42 2018 +0100 + + [ranges] Shorten and adjust stable labels + + commit fb5d52d59d6823d0e03b2e7ca85d76f43402efa8 + Author: Jens Maurer + Date: Mon Nov 26 13:22:09 2018 +0100 + + [structure.summary] Add missing templated entities + + commit 944a64419594b455759168e089c5cd075ea848be + Author: Jens Maurer + Date: Mon Nov 26 13:33:33 2018 +0100 + + [func.bind_front] Use unwrap_ref_decay_t + + commit 12c55fcdff724855444d3e3ddfcc24ad93d9dd6a + Author: Jens Maurer + Date: Mon Nov 26 13:54:46 2018 +0100 + + [dcl.attr.contract.check] Remove redundant statement that violation handler is implementation-defined + + commit ae11d65ac5df8a7e605f07bc1d36ed584002fd15 + Author: Jens Maurer + Date: Mon Nov 26 14:01:32 2018 +0100 + + [expr] Fix cross-references for 'composite pointer type' + + to refer to [expr.type], not [expr.prop]. + + commit 42f956e7e80a4dfd81608b366e4f7813332d7dc0 + Author: Jens Maurer + Date: Mon Nov 26 18:31:42 2018 +0100 + + [temp] Use 'deduced as' instead of 'deduced to' + + in comments explaining examples + + commit 602a81d2d88ec98fef3d4feeaf5b24079e1e2110 + Author: S. B. Tam + Date: Fri Oct 12 17:35:23 2018 +0800 + + [class.mem] Add opaque-enum-declaration to member-declaration + + commit 8ddcba4252b4a45194b8fdf4ebd2a439cb5e5147 + Author: Kazutoshi SATODA + Date: Tue Oct 30 08:58:23 2018 +0900 + + [conv.lval] Improve a bit more the note about std::nullptr_t case + + - "read the object" -> "access the object" + The "read" was derived from the rule at [intro.execution], but it + didn't fit well here. + - "the object" -> "the object to which the glvalue refers" + Make it clear what "the object" refers to. + + https://github.com/cplusplus/draft/pull/2372#pullrequestreview-169248002 + + commit 0b35a4688d09a385488f0d23c296afa622d7b02e + Author: Kazutoshi SATODA + Date: Thu Oct 25 02:59:31 2018 +0900 + + [conv.lval] Improve the note about std::nullptr_t case + + The meaning of "fetched from memory" is vague, and the two uses of term + "access" [defns.access] are inappropreate here because + - it causes undefined behavior to access an inactive member of a + union, based on the rule of out-of-lifetime object [basic.life]: + > The program has undefined behavior if: + > - the glvalue is used to access the object, or + - it implies reading the referenced object of std::nullptr_t, + which is defined to be a side effect for volatile-qualified case. + [intro.execution] + > Reading an object designated by a volatile glvalue, ... are all + > side effects, ... + + commit a694c9131618fd71b65faa8022cd6210dfa760f7 + Author: Eelis van der Weegen + Date: Sun Nov 11 21:31:03 2018 +0100 + + [expr.static.cast] Say 'lvalue denoting ...' instead of 'lvalue to ...' + + commit 2e054057e5a0db3e5563dd05286b04b55c3a3b87 + Author: Jens Maurer + Date: Wed Nov 21 12:02:41 2018 +0100 + + [basic.stc.dynamic.allocation] Fix cross-reference for get_new_handler + + commit d4439240b74cf044bc7626ed364eeba291ca79dd + Author: Jens Maurer + Date: Tue Oct 9 21:06:30 2018 +0200 + + [basic.type.qualifier] Clarify the definitions of const/volatile object + + commit d348800a5b0c2e594cf5e0b6e22404d52731e263 + Author: Jens Maurer + Date: Thu Oct 11 09:47:10 2018 +0200 + + [dcl.spec.auto] Return type deduction should refer to templated entity + + commit 2aa12aea978a0a79b725ce7552a1803c282a1c93 + Author: Géry Ogam + Date: Mon Nov 26 10:28:28 2018 +0100 + + [basic.lval] Correct an article in the prvalue definition + + An operator can have multiple operands. + + commit e63542071ba4acee0adb82bd1221fdb0158a4eef + Author: Casey Carter + Date: Sat Nov 17 16:29:38 2018 -0800 + + [cmp.categories,time.cal] Change "explicit constexpr" to "constexpr explicit" + + Per discussion in #2371. + + commit e6bbbbf62cddcbc6cea43a7589cfbcc48817b74b + Author: Richard Smith + Date: Mon Nov 26 00:27:52 2018 -0800 + + [unord.req] Clarify what r1 is and remove unnecessary variable e. + + commit 38f9dccc5abe1d53e28249bd09be79a25d9b2427 + Author: Dawn Perchik + Date: Fri Nov 16 02:27:56 2018 -0800 + + [unord.req] Use bullets for the list of denoting variables. + + commit e6b8936788decfb6c29ea527f1195ec3679a1195 + Author: Richard Smith + Date: Mon Nov 26 00:17:04 2018 -0800 + + [func.def] Simplify "references to functions and references to objects" + to simply "references". + + commit dafbb9445f11ad231abbf72028c29b6dd77c9334 + Author: Jens Maurer + Date: Mon Nov 19 09:44:01 2018 +0100 + + [func.not_fn,func.bind_front] Some clarifications + + 'a target object' -> 'the target object' + render 'initializer' as a grammar term and add a cross-reference + to dcl.init + add cross-references to expr.call + + commit 40fc57e9efdf5159a981cd87c9d8d765fd3f29ae + Author: Richard Smith + Date: Sun Nov 25 23:11:27 2018 -0800 + + [iterators] Remove bogus "shall"s is "Expects" elements. + + commit 9110f52c0e9550472b55845ba1c063333a94ad17 + Author: Richard Smith + Date: Sun Nov 25 21:46:09 2018 -0800 + + [range] [iterators] Replace uses of { I } -> Same& requirement. + + This form of requirement was made ill-formed by P1084R2. In its place, + use { I } -> Same, after discussion on the lib reflector. + + commit 00da6c53f744a1781a1ce23cd3026af9d87f1f8a + Author: Richard Smith + Date: Sun Nov 25 21:42:11 2018 -0800 + + [incrementable.traits] [readable.traits] Remove redundant remove_const_t + on type that cannot be const-qualified. + + commit e57b65067a5c73e20f2287b0ca0782d5d7d0333a + Author: Richard Smith + Date: Fri Nov 23 22:20:47 2018 -0800 + + [std.iterator.tags] Replace "the most specific category tag" with "a + category tag". + + The new text was present in the Ranges wording, but with no insertion / + deletion markup to indicate that an edit was to be performed. However, + consultation with LWG revealed that this was an intentional edit missing + markup. + + commit 92326665186c9c4e29f058f5b8d0ae5ea9814465 + Author: Jens Maurer + Date: Sat Nov 17 15:29:01 2018 +0100 + + [pairs.spec,tuple.creation] Simplify description + + by inlining unwrap_ref_decay_t into its point of use. + + commit d9521a91ab07548e888bd5be386822c0148a111f + Author: Richard Smith + Date: Sun Nov 25 18:44:37 2018 -0800 + + [iostream.forward.overview] Convert incomplete wording with no normative + effect to an example. + + commit 6260a047c0f3120a0570e6418f201294e6442664 + Author: Dawn Perchik + Date: Thu Nov 22 23:58:55 2018 -0800 + + [diff.cpp17.input.output] Add ill-formed comment and a still well-formed use. + + commit a0a637a0b2797b2809982836c9330052a8465172 + Author: Richard Smith + Date: Sun Nov 25 01:29:58 2018 -0800 + + [expr.prim.req.compound] Replace note that restates what + 'immediately-declared constraint' means with an example. + + commit 27797625e16a95b8946a353b09a86544c411ce61 + Author: Richard Smith + Date: Sun Nov 25 01:08:30 2018 -0800 + + [temp.param] Remove unused grammar production default-template-argument. + + commit 9b525539f0c7bf734be8e01db082fca775dbd028 + Author: Richard Smith + Date: Sun Nov 25 00:52:55 2018 -0800 + + [dcl.type.simple] Factor out decltype(e) wording into its own subclause. + + commit 4cc61d46edce136f5dfaeeee671ea58039b032e2 + Author: Richard Smith + Date: Fri Nov 23 19:55:37 2018 -0800 + + [expr.prim.req.compound] Resolve conflict between P1084R2 and P1141R2. + + Replace /qualified-concept-name/ with /type-constraint/ in grammar + for /return-type-requirement/, and rewrite the new bullet for + /return-type-requirement/ added in P1084R2 to use the term + immediately-declared constraint introduced in P1141R2. + + commit d4d65994bcf692c472cee2ed83db34e4c94266e6 + Author: Richard Smith + Date: Sat Nov 24 23:40:25 2018 -0800 + + [expr.const] Remove redundant bullet from definition of manifestly + constant-evaluated. Constexpr variables are always usable in constant + expressions. + + commit e201f3325d8a91319c37a702e50d8032759fd822 + Author: Richard Smith + Date: Sat Nov 24 23:37:02 2018 -0800 + + [expr.const] Factor out some commonality from 'manifestly + constant-evaluated' and 'potentially constant evaluated'. + + commit e58439bce8af85e6569328272c2cfb73f5fc44d6 + Author: Richard Smith + Date: Sat Nov 24 23:13:58 2018 -0800 + + [expr.const] Add missing definition of 'usable in constant expressions' + for (sub)objects and reference members. + + commit b4eec9d65bcd54430c02ac7e66c88e63360801e6 + Author: Jens Maurer + Date: Wed Nov 14 23:45:01 2018 +0100 + + [c.mb.wcs] The parameter is called 's', not 'buf' + + commit f892418bf423d6495beaf75093db3dd97aff2d14 + Author: Richard Smith + Date: Fri Nov 23 21:26:05 2018 -0800 + + [gram] Remove now-incorrect claim that a typedef-name naming a class is + a class-name. + + commit 8b70fdad014640772691057ada5b528bc8724b12 + Author: Jens Maurer + Date: Mon Nov 12 03:10:20 2018 +0100 + + [expr,class,temp] Remove vestigious references + + to pseudo-destructor-name and the removed section [expr.pseudo]. + + Add xrefdelta entry for removed section. + + commit fb22bbd60aba1f3aaf9288ab08a7feeb8e4c0101 + Author: Richard Smith + Date: Fri Nov 23 19:51:28 2018 -0800 + + [expr.prim.req.compound] Change "is" to "has a" when refering to grammar terms. + + commit 9bcfe7de3dd5bd4ad429011e169fca583bfa30b0 + Author: Eelis + Date: Tue Nov 20 23:16:11 2018 +0100 + + [dcl.fct] Add missing period after last sentence in example. (#2494) + + commit 12935b8549c0412f528b33b7795a19cda7ae8dd6 + Author: Arthur O'Dwyer + Date: Tue Nov 6 02:03:15 2018 -0500 + + [class.copy.assign] Use Oxford comma. + + Also convert some text font spaces into tcode spaces. + + commit 9437d29c92b8c2e4e779acaa2677e2cbb8800414 + Author: Jens Maurer + Date: Tue Nov 6 03:37:18 2018 +0100 + + [thread] Remove class name repeated in subheadings (#2368) + + commit 8ae6a8fbd5e0b19e0c2fad3598c3693b72081606 + Author: Jens Maurer + Date: Tue Nov 6 03:36:58 2018 +0100 + + [input.output] Remove class name repeated in subheadings (#2366) + + commit 96028f0000bbe2709bcdefe0fe3edc24862529a7 + Author: Casey Carter + Date: Wed Oct 31 04:21:52 2018 -0700 + + [iterator.requirements.general] Operations satisfy requirements, not operations (#2375) + + Drive-by: change "satisfy .... requirements" to "meet ... requirements". + + commit a43c2b30d71827325d8fdfbbd1488c570993adb7 + Author: Jens Maurer + Date: Fri Oct 19 15:17:52 2018 +0200 + + [localization] Remove class name repeated in subheadings (#2364) + + commit 9405969f396d371284945904b534bd3f3e029d47 + Author: Jens Maurer + Date: Thu Oct 18 20:39:54 2018 +0200 + + [numerics] Remove class name repeated in subheadings (#2362) + + commit 4afc80a9ab5b78cb3c1fe70495e162d40f427116 + Author: Casey Carter + Date: Wed Oct 17 02:19:26 2018 -0700 + + [output.iterators] Remove misleading italics from note (#2360) + + Since LWG asked me to remove these from P0896's OutputIterator, they probably don't belong in Cpp17OutputIterator either. + + commit 853f6bfc029f4d290c8a31da14f4282ee298cdc5 + Author: Jens Maurer + Date: Mon Oct 15 16:10:00 2018 +0200 + + [iterators] Remove class name repeated in subheadings (#2358) + + commit 3a6d922f5ef5c3c77cfe74e39563879698716768 + Author: Jens Maurer + Date: Sat Oct 13 15:07:28 2018 +0200 + + [re] Remove class name repeated in subheadings (#2356) + + commit d0bb9916b779f6b113294ce9387063cad2f4b465 + Author: Jens Maurer + Date: Sat Oct 13 10:45:05 2018 +0200 + + [utilities] Remove class name repeated in subheadings (#2355) + + commit 506ec70eab720e757555be0059c5371ff4117fba + Author: Jens Maurer + Date: Wed Oct 10 23:35:18 2018 +0200 + + [class.this] Turn redundant statement on cv-qualified constructors/destructors + into a note. + + commit 7c0e7fd6396d5509027c390d9557f9642d30db42 + Author: Jonathan Wakely + Date: Wed Oct 10 15:06:10 2018 +0100 + + [cpp.cond] Fix "carries_depencency" typo in table + + commit e8fee95850cc5a68ea09fb29f4e50c28632ed348 + Author: Jens Maurer + Date: Tue Oct 9 23:24:28 2018 +0200 + + [basic.types] Clarify that 'value representation' does not depend on the value. (#2246) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4bf758ba93..db62bcc009 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -30,13 +30,38 @@ Because of this, they can work with program-defined data structures, as long as these data structures have iterator types satisfying the assumptions on the algorithms. +\pnum +The entities defined in the \tcode{std::ranges} namespace +in this Clause are not found by argument-dependent +name lookup\iref{basic.lookup.argdep}. When found by +unqualified\iref{basic.lookup.unqual} name lookup for the +\grammarterm{postfix-expression} in a function call\iref{expr.call}, they +inhibit argument-dependent name lookup. + +\begin{example} +\begin{codeblock} +void foo() { + using namespace std::ranges; + std::vector vec{1,2,3}; + find(begin(vec), end(vec), 2); // \#1 +} +\end{codeblock} +The function call expression at \tcode{\#1} invokes \tcode{std::ranges::find}, +not \tcode{std::find}, despite that (a) the iterator type returned from \tcode{begin(vec)} +and \tcode{end(vec)} may be associated with namespace \tcode{std} and (b) +\tcode{std::find} is more specialized~(\ref{temp.func.order}) than +\tcode{std::ranges::find} since the former requires its first two parameters to +have the same type. +\end{example} + \pnum For purposes of determining the existence of data races, algorithms shall not modify objects referenced through an iterator argument unless the specification requires such modification. \pnum -Throughout this Clause, the names of template parameters +Throughout this Clause, where the template parameters are not constrained, +the names of template parameters are used to express type requirements. \begin{itemize} \item @@ -95,7 +120,9 @@ \tcode{OutputIterator1}, or \tcode{OutputIterator2}, -because output iterators must always be mutable. +because output iterators must always be mutable, nor does it affect +arguments that are constrained, for which mutability requirements are expressed +explicitly. \end{note} \pnum @@ -110,7 +137,7 @@ suffix \tcode{_if} (which follows the suffix \tcode{_copy}). \pnum -The +When not otherwise constrained, the \tcode{Predicate} parameter is used whenever an algorithm expects a function object\iref{function.objects} that, when applied to the result @@ -120,16 +147,20 @@ takes \tcode{Predicate pred} as its argument and \tcode{first} -as its iterator argument, it should work correctly in the -construct +as its iterator argument with value type \tcode{T}, +it should work correctly in the construct \tcode{pred(*first)} contextually converted to \tcode{bool}\iref{conv}. The function object \tcode{pred} shall not apply any non-constant function through the dereferenced iterator. +Given a glvalue \tcode{u} of type (possibly \tcode{const}) \tcode{T} that +designates the same object as \tcode{*first}, +\tcode{pred(u)} shall be a valid expression +that is equal to \tcode{pred(*first)}. \pnum -The +When not otherwise constrained, the \tcode{BinaryPredicate} parameter is used whenever an algorithm expects a function object that when applied to the result of dereferencing two corresponding iterators or to dereferencing an @@ -142,9 +173,10 @@ In other words, if an algorithm takes \tcode{BinaryPredicate binary_pred} as its argument and \tcode{first1} and \tcode{first2} as -its iterator arguments, it should work correctly in -the construct +its iterator arguments with respective value types \tcode{T1} and \tcode{T2}, +it should work correctly in the construct \tcode{binary_pred(*first1, *first2)} contextually converted to \tcode{bool}\iref{conv}. +Unless otherwise specified, \tcode{BinaryPredicate} always takes the first iterator's \tcode{value_type} @@ -155,6 +187,19 @@ construct \tcode{binary_pred(*first1, value)} contextually converted to \tcode{bool}\iref{conv}. \tcode{binary_pred} shall not apply any non-constant function through the dereferenced iterators. +Given a glvalue \tcode{u} of type (possibly \tcode{const}) \tcode{T1} that +designates the same object as \tcode{*first1}, and +a glvalue \tcode{v} of type (possibly \tcode{const}) \tcode{T2} that +designates the same object as +\tcode{*first2}, +\tcode{binary_pred(u, *first2)}, +\tcode{binary_pred(*first1, v)}, and +\tcode{binary_pred(u, v)} +shall each be a valid expression that is equal to +\tcode{binary_pred(*first1, *first2)}, and +\tcode{binary_pred(u, value)} +shall be a valid expression that is equal to +\tcode{binary_pred(*first1, value)}. \pnum The parameters @@ -180,29 +225,63 @@ either \tcode{true} or \tcode{false} in boolean contexts. \pnum -In the description of the algorithms operators -\tcode{+} -and -\tcode{-} -are used for some of the iterator categories for which -they do not have to be defined. +In the description of the algorithms, operator \tcode{+} +is used for some of the iterator categories for which +it does not have to be defined. In these cases the semantics of -\tcode{a+n} -is the same as that of - +\tcode{a + n} +are the same as those of \begin{codeblock} -X tmp = a; -advance(tmp, n); +auto tmp = a; +for (; n < 0; ++n) --tmp; +for (; n > 0; --n) ++tmp; return tmp; \end{codeblock} - -and that of -\tcode{b-a} -is the same as of - +Similarly, operator \tcode{-} is used for some +combinations of iterators and sentinel types for which +it does not have to be defined. If \range{a}{b} denotes a range, +the semantics of \tcode{b - a} in these cases are the same as those of \begin{codeblock} -return distance(a, b); +iter_difference_t> n = 0; +for (auto tmp = a; tmp != b; ++tmp) ++n; +return n; \end{codeblock} +and if \range{b}{a} denotes a range, the same as those of +\begin{codeblock} +iter_difference_t> n = 0; +for (auto tmp = b; tmp != a; ++tmp) --n; +return n; +\end{codeblock} + +\pnum +In the description of algorithm return values, a sentinel value \tcode{s} +denoting the end of a range \range{i}{s} is sometimes +returned where an iterator is expected. In these cases, the semantics are as +if the sentinel is converted into an iterator using +\tcode{ranges::next(i, s)}. + +\pnum +Overloads of algorithms that take \libconcept{Range} arguments\iref{range.range} +behave as if they are implemented by calling \tcode{ranges::begin} and +\tcode{ranges::end} on the \libconcept{Range}(s) and dispatching +to the overload in namespace \tcode{ranges} that takes +separate iterator and sentinel arguments. + +\pnum +The number and order of deducible template parameters for algorithm declarations +are unspecified, except where explicitly stated otherwise. +\begin{note} +Consequently, the algorithms may not be called with +explicitly-specified template argument lists. +\end{note} + +\pnum +The class templates \tcode{binary_transform_result}, +\tcode{for_each_result}, \tcode{minmax_result}, \tcode{mismatch_result}, +\tcode{copy_result}, and +\tcode{partition_copy_result} have the template parameters, data members, and +special members specified above. They have no base classes or members other than +those specified. \rSec1[algorithms.parallel]{Parallel algorithms} @@ -496,6 +575,15 @@ bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 = {}); + } + // \ref{alg.any_of}, any of template constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); @@ -503,6 +591,15 @@ bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 = {}); + } + // \ref{alg.none_of}, none of template constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); @@ -510,12 +607,39 @@ bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 = {}); + } + // \ref{alg.foreach}, for each template constexpr Function for_each(InputIterator first, InputIterator last, Function f); template void for_each(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Function f); + + namespace ranges { + template + struct for_each_result { + I in; + F fun; + }; + + 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 constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); template @@ -545,6 +669,30 @@ 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 = {}); + } + // \ref{alg.find.end}, find end template constexpr ForwardIterator1 @@ -568,6 +716,21 @@ 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 = {}); + } + // \ref{alg.find.first.of}, find first template constexpr InputIterator @@ -591,6 +754,23 @@ 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 = {}); + } + // \ref{alg.adjacent.find}, adjacent find template constexpr ForwardIterator @@ -609,6 +789,17 @@ 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 = {}); + } + // \ref{alg.count}, count template constexpr typename iterator_traits::difference_type @@ -625,6 +816,25 @@ count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 = {}); + } + // \ref{mismatch}, mismatch template constexpr pair @@ -667,6 +877,29 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + namespace ranges { + template + struct mismatch_result { + I1 in1; + I2 in2; + }; + + 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 = {}); + } + // \ref{alg.equal}, equal template constexpr bool equal(InputIterator1 first1, InputIterator1 last1, @@ -701,6 +934,20 @@ 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 = {}); + } + // \ref{alg.is_permutation}, is permutation template constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, @@ -716,6 +963,21 @@ 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 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 = {}); + } + // \ref{alg.search}, search template constexpr ForwardIterator1 @@ -738,6 +1000,23 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 + 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 constexpr ForwardIterator search_n(ForwardIterator first, ForwardIterator last, @@ -760,6 +1039,21 @@ Size count, const T& value, BinaryPredicate pred); + 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 constexpr ForwardIterator search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); @@ -773,6 +1067,24 @@ ForwardIterator2 copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + + namespace ranges { + template + struct copy_result { + I in; + O out; + }; + + 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 constexpr OutputIterator copy_n(InputIterator first, Size n, OutputIterator result); @@ -781,6 +1093,17 @@ ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, Size n, ForwardIterator2 result); + + namespace ranges { + template + using copy_n_result = copy_result; + + template + requires IndirectlyCopyable + constexpr copy_n_result + copy_n(I first, iter_difference_t n, O result); + } + template constexpr OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); @@ -789,11 +1112,42 @@ ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); + + namespace ranges { + template + using copy_if_result = copy_result; + + 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 constexpr BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); + namespace ranges { + template + using copy_backward_result = copy_result; + + 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); + } + // \ref{alg.move}, move template constexpr OutputIterator move(InputIterator first, InputIterator last, @@ -803,11 +1157,40 @@ ForwardIterator2 move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + + namespace ranges { + template + using move_result = copy_result; + + 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 constexpr BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); + namespace ranges { + template + using move_backward_result = copy_result; + + 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); + } + // \ref{alg.swap}, swap template constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, @@ -816,13 +1199,28 @@ ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); + + namespace ranges { + template + using swap_ranges_result = mismatch_result; + + 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 constexpr void iter_swap(ForwardIterator1 a, ForwardIterator2 b); // \ref{alg.transform}, transform template constexpr OutputIterator - transform(InputIterator first, InputIterator last, + transform(InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op); template @@ -834,7 +1232,7 @@ class UnaryOperation> ForwardIterator2 transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 result, UnaryOperation op); template @@ -844,6 +1242,45 @@ ForwardIterator2 first2, ForwardIterator result, BinaryOperation binary_op); + namespace ranges { + template + using unary_transform_result = copy_result; + + 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 + struct binary_transform_result { + I1 in1; + I2 in2; + O out; + }; + + 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 = {}); + } + // \ref{alg.replace}, replace template constexpr void replace(ForwardIterator first, ForwardIterator last, @@ -859,6 +1296,29 @@ void replace_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, @@ -879,6 +1339,42 @@ ForwardIterator2 result, Predicate pred, const T& new_value); + namespace ranges { + template + using replace_copy_result = copy_result; + + 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 + using replace_copy_if_result = copy_result; + + 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 = {}); + } + // \ref{alg.fill}, fill template constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); @@ -892,6 +1388,15 @@ ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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); + } + // \ref{alg.generate}, generate template constexpr void generate(ForwardIterator first, ForwardIterator last, @@ -906,6 +1411,18 @@ ForwardIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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); + } + // \ref{alg.remove}, remove template constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, @@ -921,6 +1438,26 @@ ForwardIterator remove_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr OutputIterator remove_copy(InputIterator first, InputIterator last, @@ -942,6 +1479,37 @@ ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); + namespace ranges { + template + using remove_copy_result = copy_result; + + 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 + using remove_copy_if_result = copy_result; + + 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 = {}); + } + // \ref{alg.unique}, unique template constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); @@ -955,6 +1523,18 @@ ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr OutputIterator unique_copy(InputIterator first, InputIterator last, @@ -975,12 +1555,44 @@ ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); + namespace ranges { + template + using unique_copy_result = copy_result; + + 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 = {}); + } + // \ref{alg.reverse}, reverse template constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); template void reverse(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, @@ -991,6 +1603,20 @@ BidirectionalIterator first, BidirectionalIterator last, ForwardIterator result); + namespace ranges { + template + using reverse_copy_result = copy_result; + + 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); + } + // \ref{alg.rotate}, rotate template constexpr ForwardIterator rotate(ForwardIterator first, @@ -1001,6 +1627,15 @@ ForwardIterator first, ForwardIterator middle, ForwardIterator last); + + namespace ranges { + template S> + constexpr subrange rotate(I first, I middle, S last); + template + requires Permutable> + constexpr safe_subrange_t rotate(R&& r, iterator_t middle); + } + template constexpr OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, @@ -1011,6 +1646,20 @@ ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result); + namespace ranges { + template + using rotate_copy_result = copy_result; + + template S, WeaklyIncrementable O> + requires IndirectlyCopyable + constexpr rotate_copy_result + rotate_copy(I first, I middle, S last, O result); + template + requires IndirectlyCopyable, O> + constexpr rotate_copy_result, O> + rotate_copy(R&& r, iterator_t middle, O result); + } + // \ref{alg.random.sample}, sample template @@ -1024,6 +1673,19 @@ RandomAccessIterator last, UniformRandomBitGenerator&& g); + namespace ranges { + template S, class Gen> + requires Permutable && + UniformRandomBitGenerator> && + ConvertibleTo, iter_difference_t> + I shuffle(I first, S last, Gen&& g); + template + requires Permutable> && + UniformRandomBitGenerator> && + ConvertibleTo, iter_difference_t>> + safe_iterator_t shuffle(R&& r, Gen&& g); + } + // \ref{alg.shift}, shift template constexpr ForwardIterator @@ -1059,6 +1721,18 @@ 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 void stable_sort(RandomAccessIterator first, RandomAccessIterator last); template @@ -1072,6 +1746,17 @@ 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 constexpr void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, @@ -1090,6 +1775,20 @@ RandomAccessIterator first, RandomAccessIterator middle, 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, class Proj = identity> + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + partial_sort(R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); + } + template constexpr RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, @@ -1115,6 +1814,26 @@ RandomAccessIterator result_first, 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 constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); template @@ -1127,6 +1846,16 @@ bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); + + 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 constexpr ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); @@ -1144,6 +1873,16 @@ 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 = {}); + } + // \ref{alg.nth.element}, Nth element template constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, @@ -1160,6 +1899,18 @@ 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, class Proj = identity> + requires Sortable, Comp, Proj> + constexpr safe_iterator_t + nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); + } + // \ref{alg.binary.search}, binary search template constexpr ForwardIterator @@ -1170,6 +1921,18 @@ 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 constexpr ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, @@ -1179,6 +1942,17 @@ 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 constexpr pair equal_range(ForwardIterator first, ForwardIterator last, @@ -1188,6 +1962,18 @@ equal_range(ForwardIterator first, 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 constexpr bool binary_search(ForwardIterator first, ForwardIterator last, @@ -1197,6 +1983,18 @@ 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 = {}); + } + // \ref{alg.partitions}, partitions template constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); @@ -1204,6 +2002,15 @@ bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr ForwardIterator partition(ForwardIterator first, ForwardIterator last, @@ -1213,6 +2020,19 @@ 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 BidirectionalIterator stable_partition(BidirectionalIterator first, BidirectionalIterator last, @@ -1222,6 +2042,18 @@ 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 constexpr pair @@ -1235,11 +2067,45 @@ ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); + + namespace ranges { + template + struct partition_copy_result { + I in; + O1 out1; + O2 out2; + }; + + 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 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 = {}); + } + // \ref{alg.merge}, merge template constexpr OutputIterator @@ -1267,6 +2133,25 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); + namespace ranges { + template + using merge_result = binary_transform_result; + + 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 void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, @@ -1286,6 +2171,18 @@ 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, class Proj = identity> + requires Sortable, Comp, Proj> + safe_iterator_t + inplace_merge(R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); + } + // \ref{alg.set.operations}, set operations template constexpr bool includes(InputIterator1 first1, InputIterator1 last1, @@ -1305,6 +2202,21 @@ 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 constexpr OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, @@ -1330,6 +2242,25 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); + namespace ranges { + template + using set_union_result = binary_transform_result; + + 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 constexpr OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, @@ -1355,6 +2286,25 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); + namespace ranges { + template + using set_intersection_result = binary_transform_result; + + 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 constexpr OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, @@ -1380,6 +2330,25 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); + namespace ranges { + template + using set_difference_result = copy_result; + + 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 constexpr OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, @@ -1405,6 +2374,26 @@ ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); + namespace ranges { + template + using set_symmetric_difference_result = binary_transform_result; + + 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 = {}); + } + // \ref{alg.heap.operations}, heap operations template constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); @@ -1412,24 +2401,72 @@ 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 constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); template 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 constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); template 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 constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); template 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 constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); template @@ -1442,6 +2479,16 @@ bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last, Compare comp); + + 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 constexpr RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); @@ -1459,6 +2506,16 @@ 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 = {}); + } + // \ref{alg.min.max}, minimum and maximum template constexpr const T& min(const T& a, const T& b); template @@ -1468,6 +2525,20 @@ template constexpr T min(initializer_list t, Compare comp); + namespace ranges { + template> Comp = ranges::less<>> + constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + template> 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 constexpr const T& max(const T& a, const T& b); template constexpr const T& max(const T& a, const T& b, Compare comp); @@ -1476,6 +2547,20 @@ template constexpr T max(initializer_list t, Compare comp); + namespace ranges { + template> Comp = ranges::less<>> + constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + template> 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 constexpr pair minmax(const T& a, const T& b); template constexpr pair minmax(const T& a, const T& b, Compare comp); @@ -1484,6 +2569,28 @@ template constexpr pair minmax(initializer_list t, Compare comp); + namespace ranges { + template + struct minmax_result { + T min; + T max; + }; + + template> Comp = ranges::less<>> + constexpr minmax_result + minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + 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 constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); template @@ -1496,6 +2603,17 @@ ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); template @@ -1508,6 +2626,17 @@ ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 constexpr pair minmax_element(ForwardIterator first, ForwardIterator last); @@ -1523,6 +2652,17 @@ minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} 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 = {}); + } + // \ref{alg.clamp}, bounded value template constexpr const T& clamp(const T& v, const T& lo, const T& hi); @@ -1552,6 +2692,23 @@ 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 = {}); + } + // \ref{alg.3way}, three-way comparison algorithms template constexpr auto compare_3way(const T& a, const U& b); @@ -1573,12 +2730,39 @@ template 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 constexpr bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last); template 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 = {}); + } } \end{codeblock} @@ -1593,16 +2777,30 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{true} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +Let $E$ be \tcode{pred(*i)} and \tcode{invoke(pred, invoke(proj, *i))} +for the overloads in namespace \tcode{std} and \tcode{std::ranges}, respectively. + +\pnum +\returns +\tcode{false} if $E$ is \tcode{false} for some iterator \tcode{i} in the +range \range{first}{last}, and \tcode{true} otherwise. \pnum -\complexity At most \tcode{last - first} applications of the predicate. +\complexity At most \tcode{last - first} applications of the predicate +and any projection. \end{itemdescr} \rSec2[alg.any_of]{Any of} @@ -1614,16 +2812,29 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{false} if \range{first}{last} is empty or -if there is no iterator \tcode{i} in the range -\range{first}{last} such that \tcode{pred(*i)} is \tcode{true}, and \tcode{true} otherwise. +Let $E$ be \tcode{pred(*i)} and \tcode{invoke(pred, invoke(proj, *i))} +for the overloads in namespace \tcode{std} and \tcode{std::ranges}, respectively. +\pnum +\returns +\tcode{true} if $E$ is \tcode{true} for some iterator \tcode{i} +in the range \range{first}{last}, and \tcode{false} otherwise. \pnum -\complexity At most \tcode{last - first} applications of the predicate. +\complexity At most \tcode{last - first} applications of the predicate +and any projection. \end{itemdescr} \rSec2[alg.none_of]{None of} @@ -1635,16 +2846,30 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{false} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +Let $E$ be \tcode{pred(*i)} and \tcode{invoke(pred, invoke(proj, *i))} +for the overloads in namespace \tcode{std} and \tcode{std::ranges}, respectively. + +\pnum +\returns +\tcode{false} if $E$ is \tcode{true} for some iterator \tcode{i} +in the range \range{first}{last}, and \tcode{true} otherwise. \pnum -\complexity At most \tcode{last - first} applications of the predicate. +\complexity At most \tcode{last - first} applications of the predicate +and any projection. \end{itemdescr} \rSec2[alg.foreach]{For each} @@ -1731,6 +2956,59 @@ \end{note} \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls +\tcode{invoke(f, invoke(proj, *i))} for every iterator +\tcode{i} in the range +\range{first}{last}, +starting from +\tcode{first} +and proceeding to +\tcode{last - 1}. +\begin{note} +If the result of +\tcode{invoke(proj, *i)} is a mutable reference, \tcode{f} may apply +non-constant functions. +\end{note} + +\pnum +\returns +\tcode{\{last, std::move(f)\}}. + +\pnum +\complexity +Applies \tcode{f} and \tcode{proj} +exactly +\tcode{last - first} +times. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. + +\pnum +\begin{note} +The overloads in namespace \tcode{ranges} require \tcode{Fun} to model +\libconcept{CopyConstructible}. +\end{note} +\end{itemdescr} + \indexlibrary{\idxcode{for_each_n}}% \begin{itemdecl} template @@ -1827,27 +3105,62 @@ constexpr InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred); template - ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + ForwardIterator find_if_not(ExecutionPolicy&& exec, + 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{*i == value} for \tcode{find}, +\item \tcode{pred(*i) != false} for \tcode{find_if}, +\item \tcode{pred(*i) == false} for \tcode{find_if_not}, +\item \tcode{invoke(proj, *i) == value} for \tcode{ranges::find}, +\item \tcode{invoke(pred, invoke(proj, *i)) != false} for \tcode{ranges::find_if}, +\item \tcode{invoke(pred, invoke(proj, *i)) == false} for \tcode{ranges::find_if_not}. +\end{itemize} + \pnum \returns The first iterator \tcode{i} in the range \range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value}, \tcode{pred(*i) != false}, \tcode{pred(*i) == false}. +for which +$E$ is \tcode{true}. Returns \tcode{last} if no such iterator is found. \pnum \complexity At most \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \end{itemdescr} \rSec2[alg.find.end]{Find end} @@ -1877,32 +3190,62 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\effects -Finds a subsequence of equal values in a sequence. +Let: +\begin{itemize} +\item \tcode{pred} be \tcode{equal_to\{\}} for the overloads with no parameter +\tcode{pred}. -\pnum -\returns -The last iterator -\tcode{i} +\item $E$ be: +\begin{itemize} +\item \tcode{pred(*(i + n), *(first2 + n))} +for the overloads in namespace \tcode{std}, + +\item \tcode{invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n)))} +for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\item \tcode{i} be \tcode{last1} if \range{first2}{last2} is empty, +or if \tcode{(last2 - first2) > (last1 - first1)} is \tcode{true}, +or if there is no iterator in the range \range{first1}{last1 - (last2 - first2)} such that for every non-negative integer -\tcode{n < (last2 - first2)}, -the following corresponding conditions hold: -\tcode{*(i + n) == *(\brk{}first2 + n), pred(*(i + n), *(first2 + n)) != false}. -Returns \tcode{last1} -if -\range{first2}{last2} is empty or if -no such iterator is found. +\tcode{n < (last2 - first2)}, $E$ is \tcode{true}. +Otherwise \tcode{i} is the last such iterator +in \range{first1}{last1 - (last2 - first2)}. +\end{itemize} + +\pnum +\returns +\begin{itemize} +\item \tcode{i} for the overloads in namespace \tcode{std}, and +\item \tcode{\{i, i + (i == last1 ? 0 : last2 - first2)\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity At most \tcode{(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)} -applications of the corresponding predicate. +applications of the corresponding predicate and any projections. \end{itemdescr} \rSec2[alg.find.first.of]{Find first} @@ -1932,9 +3275,35 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{*i == *j} for the overloads with no parameter \tcode{pred}, +\item \tcode{pred(*i, *j) != false} for the overloads with a parameter \tcode{pred} and no parameter \tcode{proj1}, +\item \tcode{invoke(pred, invoke(proj1, *i), invoke(proj2, *j)) != false} for the overloads with parameters \tcode{pred} and \tcode{proj1}. +\end{itemize} + \pnum \effects Finds an element that matches one of a set of values. @@ -1947,9 +3316,7 @@ such that for some iterator \tcode{j} -in the range \range{first2}{last2} -the following conditions hold: -\tcode{*i == *j, pred(*i,*j) != false}. +in the range \range{first2}{last2} $E$ holds. Returns \tcode{last1} if \range{first2}{last2} is empty or if no such iterator is found. @@ -1958,7 +3325,7 @@ \complexity At most \tcode{(last1-first1) * (last2-first2)} -applications of the corresponding predicate. +applications of the corresponding predicate and any projections. \end{itemdescr} \rSec2[alg.adjacent.find]{Adjacent find} @@ -1982,9 +3349,29 @@ adjacent_find(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item \tcode{*i == *(i + 1)} for the overloads with no parameter \tcode{pred}, +\item \tcode{pred(*i, *(i + 1)) != false} for the overloads with a parameter \tcode{pred} and no parameter \tcode{proj}, +\item \tcode{invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))) != false} for the overloads with both parameters \tcode{pred} and \tcode{proj}. +\end{itemize} + \pnum \returns The first iterator @@ -1996,20 +3383,19 @@ are in the range \range{first}{last} -for which -the following corresponding conditions hold: -\tcode{*i == *(i + 1), pred(*i, *(i + 1)) != false}. +for which $E$ holds. Returns \tcode{last} if no such iterator is found. \pnum \complexity For the overloads with no \tcode{ExecutionPolicy}, exactly -\tcode{min((i - first) + 1, (last - first) - 1)} +\[ \min(\tcode{(i - first) + 1}, \ \tcode{(last - first) - 1}) \] applications of the corresponding predicate, where \tcode{i} is \tcode{adjacent_find}'s return value. For the overloads with an \tcode{ExecutionPolicy}, -\bigoh{\tcode{last - first}} applications of the corresponding predicate. +\bigoh{\tcode{last - first}} applications of the corresponding predicate, +and no more than twice as many applications of any projection. \end{itemdescr} \rSec2[alg.count]{Count} @@ -2032,23 +3418,53 @@ typename iterator_traits::difference_type 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{*i == value} for the overloads + with no parameter \tcode{pred} or \tcode{proj}, +\item \tcode{pred(*i) != false} for the overloads + with a parameter \tcode{pred} but no parameter \tcode{proj}, +\item \tcode{invoke(proj, *i) == value} for the overloads + with a parameter \tcode{proj} but no parameter \tcode{pred}, +\item \tcode{invoke(pred, invoke(proj, *i)) != false} for the overloads + with both parameters \tcode{proj} and \tcode{pred}. +\end{itemize} + \pnum \effects Returns the number of iterators \tcode{i} in the range \range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value, pred(*i) != false}. +for which $E$ holds. \pnum \complexity Exactly \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \end{itemdescr} \rSec2[mismatch]{Mismatch} @@ -2100,29 +3516,49 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +Let \tcode{last2} be \tcode{first2 + (last1 - first1)} for the overloads with no parameter \tcode{last2} or \tcode{r2}. \pnum -\returns -A pair of iterators \tcode{first1 + n} and -\tcode{first2 + n}, where \tcode{n} is the smallest integer -such that, respectively, +Let $E$ be: \begin{itemize} -\item \tcode{!(*(first1 + n) == *(first2 + n))} or -\item \tcode{pred(*(first1 + n), *(first2 + n)) == false}, +\setlength{\emergencystretch}{1em} +\item \tcode{!(*(first1 + n) == *(first2 + n))} for the overloads with no parameter \tcode{pred}, +\item \tcode{pred(*(first1 + n), *(first2 + n)) == false} for the overloads with a parameter \tcode{pred} and no parameter \tcode{proj1}, +\item \tcode{!invoke(pred, invoke(proj1, *(first1 + n)), invoke(proj2, *(first2 + n)))} for the overloads with both parameters \tcode{pred} and \tcode{proj1}. \end{itemize} -or \tcode{min(last1 - first1, last2 - first2)} if no such integer exists. + +\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. \pnum \complexity At most -\tcode{min(last1 - first1, last2 - first2)} -applications of the corresponding predicate. +$\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ +applications of the corresponding predicate and any projections. \end{itemdescr} \rSec2[alg.equal]{Equal} @@ -2166,12 +3602,37 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +Let: +\begin{itemize} +\item \tcode{last2} be \tcode{first2 + (last1 - first1)} for the overloads with no parameter \tcode{last2} or \tcode{r2}, + +\item \tcode{pred} be \tcode{equal_to\{\}} for the overloads with no parameter \tcode{pred}, + +\item $E$ be: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item \tcode{pred(*i, *(first2 + (i - first1)))} for the overloads with no parameter \tcode{proj1}, +\item \tcode{invoke(pred, invoke(proj1, *i), invoke(proj2, *(first2 + (i - first1))))} for the overloads with parameter \tcode{proj1}. +\end{itemize} +\end{itemize} \pnum \returns @@ -2181,54 +3642,38 @@ \tcode{false}. Otherwise return \tcode{true} -if for every iterator +if $E$ holds for every iterator \tcode{i} in the range \range{first1}{last1} -the following corresponding conditions hold: -\tcode{*i == *(first2 + (i - first1)), pred(*i, *(first2 + (i - first1))) != false}. Otherwise, returns \tcode{false}. \pnum \complexity +If the types of \tcode{first1}, \tcode{last1}, \tcode{first2}, and \tcode{last2}: \begin{itemize} -\item -For the overloads with no \tcode{ExecutionPolicy}, -\begin{itemize} -\item -if -\tcode{InputIterator1} -and -\tcode{InputIterator2} -meet the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} +\item meet the \oldconcept{RandomAccessIterator} + requirements\iref{random.access.iterators} + for the overloads in namespace \tcode{std}, or +\item pairwise model \tcode{SizedSentinel}\iref{iterator.concept.sizedsentinel} for the +overloads in namespace \tcode{ranges}, +\end{itemize} and \tcode{last1 - first1 != last2 - first2}, then -no applications of the corresponding predicate; otherwise, - +no applications of the corresponding predicate and each projection; otherwise, +\begin{itemize} \item +For the overloads with no \tcode{ExecutionPolicy}, at most -$\min(\tcode{last1 - first1}, \tcode{last2 - first2})$ -applications of the corresponding predicate. -\end{itemize} +$\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ +applications of the corresponding predicate and any projections. \item For the overloads with an \tcode{ExecutionPolicy}, -\begin{itemize} -\item -if -\tcode{ForwardIterator1} -and -\tcode{ForwardIterator2} -meet the \oldconcept{RandomAccessIterator} requirements and -\tcode{last1 - first1 != last2 - first2}, then -no applications of the corresponding predicate; otherwise, - -\item -\bigoh{\min(\tcode{last1 - first1}, \tcode{last2 - first2})} applications +\bigoh{\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})} applications of the corresponding predicate. \end{itemize} -\end{itemize} \end{itemdescr} \rSec2[alg.is_permutation]{Is permutation} @@ -2280,6 +3725,47 @@ worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. +Otherwise return \tcode{true} if there exists a permutation of the elements in the +range \range{first2}{last2}, bounded by \range{pfirst}{plast}, such that +\tcode{ranges::equal(first1, last1, pfirst, plast, pred, proj1, proj2)} returns \tcode{true}; +otherwise, returns \tcode{false}. + +\pnum +\complexity +No applications of the corresponding predicate and projections if: +\begin{itemize} +\item \tcode{S1} and \tcode{I1} model \libconcept{SizedSentinel}, +\item \tcode{S2} and \tcode{I2} model \libconcept{SizedSentinel}, and +\item \tcode{last1 - first1 != last2 - first2}. +\end{itemize} +Otherwise, exactly \tcode{last1 - first1} applications of the +corresponding predicate and projections if +\tcode{ranges::equal(\brk{}first1, last1, first2, last2, pred, proj1, proj2)} +would return \tcode{true}; otherwise, at +worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. +\end{itemdescr} + \rSec2[alg.search]{Search} \indexlibrary{\idxcode{search}}% @@ -2310,10 +3796,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Finds a subsequence of equal values in a sequence. - \pnum \returns The first iterator @@ -2337,6 +3819,53 @@ applications of the corresponding predicate. \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item \tcode{\{i, i + (last2 - first2)\}}, where \tcode{i} is +the first iterator in the range \range{first1}{last1 - (last2 - first2)} +such that for every non-negative integer +\tcode{n} +less than +\tcode{last2 - first2} +the condition +\begin{codeblock} +bool(invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n)))) +\end{codeblock} +is \tcode{true}: + +\item Returns +\tcode{\{last1, last1\}} +if no such iterator exists. +\end{itemize} + +\pnum +\complexity +At most +\tcode{(last1 - first1) * (last2 - first2)} +applications of the corresponding predicate and projections. +\end{itemdescr} + \indexlibrary{\idxcode{search_n}}% \begin{itemdecl} template @@ -2371,10 +3900,6 @@ \tcode{Size} shall be convertible to integral type~(\ref{conv.integral}, \ref{class.conv}). -\pnum -\effects -Finds a subsequence of equal values in a sequence. - \pnum \returns The first iterator @@ -2396,6 +3921,45 @@ applications of the corresponding predicate. \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\{i, i + count\}} where \tcode{i} is the first iterator +in the range \range{first}{last - count} +such that for every non-negative integer +\tcode{n} +less than +\tcode{count}, +the following condition holds: +\tcode{invoke(pred, invoke(proj, *(i + n)), value)}. +Returns \tcode{\{last, last\}} +if no such iterator is found. + +\pnum +\complexity +At most +\tcode{last - first} +applications of the corresponding predicate and projection. +\end{itemdescr} + \indexlibrary{\idxcode{search}}% \begin{itemdecl} template @@ -2423,20 +3987,42 @@ template 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + \pnum \requires \tcode{result} shall not be in the range \range{first}{last}. \pnum -\effects Copies elements in the range \range{first}{last} into the range \range{result}{result + (last - first)} starting from \tcode{first} and proceeding to \tcode{last}. For each non-negative integer \tcode{n < (last - first)}, performs \tcode{*(result + n) = *(first + n)}. +\effects Copies elements in the range \range{first}{last} into the range \range{result}{result + $N$} starting from \tcode{first} and proceeding to \tcode{last}. +For each non-negative integer $n < N$, performs \tcode{*(result + $n$) = *(first + $n$)}. \pnum -\returns \tcode{result + (last - first)}. +\returns +\begin{itemize} +\item +\tcode{result + $N$} for the overload in namespace \tcode{std}, or +\item +\tcode{\{last, result + $N$\}} for the overloads in +namespace \tcode{ranges}. +\end{itemize} \pnum -\complexity Exactly \tcode{last - first} assignments. +\complexity Exactly $N$ assignments. \end{itemdescr} \indexlibrary{\idxcode{copy}}% @@ -2474,18 +4060,35 @@ ForwardIterator2 copy_n(ExecutionPolicy&& exec, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $M$ be $\max(\tcode{n}, 0)$. + \pnum \effects For each non-negative integer -$i < n$, performs \tcode{*(result + i) = *(first + i)}. +$i < M$, performs \tcode{*(result + i) = *(first + i)}. \pnum -\returns \tcode{result + n}. +\returns +\begin{itemize} +\item +\tcode{result + $M$} for the overloads in namespace \tcode{std}, or +\item +\tcode{\{first + $M$, result + $M$\}} + for the overload in namespace \tcode{ranges}. +\end{itemize} \pnum -\complexity Exactly \tcode{n} assignments. +\complexity Exactly $M$ assignments. \end{itemdescr} \indexlibrary{\idxcode{copy_if}}% @@ -2498,9 +4101,32 @@ ForwardIterator2 copy_if(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{bool(pred(*i))} for the overloads in namespace \tcode{std}, or +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for the overloads in + namespace \tcode{ranges}. +\end{itemize} +and $N$ be the number of iterators \tcode{i} in the range \range{first}{last} +for which the condition $E$ holds. + \pnum \requires The ranges \range{first}{last} and \range{result}{result + (last - first)} shall not overlap. \begin{note} @@ -2511,13 +4137,18 @@ \pnum \effects Copies all of the elements referred to by the iterator \tcode{i} in the range \range{first}{last} -for which \tcode{pred(*i)} is \tcode{true}. +for which $E$ is \tcode{true}. \pnum -\returns The end of the resulting range. +\returns +\begin{itemize} +\item \tcode{result + $N$} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last, result + $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum -\complexity Exactly \tcode{last - first} applications of the corresponding predicate. +\complexity Exactly \tcode{last - first} applications of the corresponding predicate and any projection. \pnum \remarks Stable\iref{algorithm.stable}. @@ -2530,9 +4161,23 @@ copy_backward(BidirectionalIterator1 first, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + \pnum \requires \tcode{result} @@ -2543,28 +4188,31 @@ \effects Copies elements in the range \range{first}{last} into the -range \range{result - (last-first)}{result} +range \range{result - $N$}{result} starting from \tcode{last - 1} and proceeding to \tcode{first}.\footnote{\tcode{copy_backward} should be used instead of copy when \tcode{last} is in the range -\range{result - (last - first)}{result}.} +\range{result - $N$}{result}.} For each positive integer -\tcode{n <= (last - first)}, +$n \le N$, performs -\tcode{*(result - n) = *(last - n)}. +\tcode{*(result - $n$) = *(last - $n$)}. \pnum \returns -\tcode{result - (last - first)}. +\begin{itemize} +\item \tcode{result - $N$} + for the overload in namespace \tcode{std}, or +\item \tcode{\{last, result - $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Exactly $N$ assignments. \end{itemdescr} \rSec2[alg.move]{Move} @@ -2574,9 +4222,28 @@ template 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{std::move(*(first + $n$))} for the overload in namespace \tcode{std}, or +\item \tcode{ranges::iter_move(first + $n$)} for the overloads in namespace \tcode{ranges}. +\end{itemize} +Let $N$ be \tcode{last - first}. + \pnum \requires \tcode{result} @@ -2586,22 +4253,26 @@ \pnum \effects Moves elements in the range \range{first}{last} -into the range \range{result}{result + (last - first)} -starting from first and proceeding to last. +into the range \range{result}{result + $N$} +starting from \tcode{first} and proceeding to \tcode{last}. For each non-negative integer -\tcode{n < (last-first)}, +$n < N$, performs -\tcode{*(result + n)} \tcode{= std::move(*(first + n))}. +\tcode{*(result + $n$) = $E$}. \pnum \returns -\tcode{result + (last - first)}. +\begin{itemize} +\item +\tcode{result + $N$} for the overload in namespace \tcode{std}, or +\item +\tcode{\{last, result + $N$\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first} -move assignments. +Exactly $N$ assignments. \end{itemdescr} \indexlibrary{\idxcode{move}!algorithm}% @@ -2613,21 +4284,24 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + \pnum \requires The ranges \range{first}{last} and -\range{result}{result + (last - first)} shall not overlap. +\range{result}{result + $N$} shall not overlap. \pnum \effects Moves elements in the range \range{first}{last} into -the range \range{result}{result + (last - first)}. -For each non-negative integer \tcode{n < (last - first)}, -performs \tcode{*(result + n) = std::\brk{}move(*(first + n))}. +the range \range{result}{result + $N$}. +For each non-negative integer $n < N$, +performs \tcode{*(result + $n$) = std::\brk{}move(*(first + $n$))}. \pnum -\returns \tcode{result + (last - first)}. +\returns \tcode{result + $N$}. \pnum -\complexity Exactly \tcode{last - first} assignments. +\complexity Exactly $N$ assignments. \end{itemdescr} \indexlibrary{\idxcode{move_backward}}% @@ -2636,9 +4310,28 @@ constexpr BidirectionalIterator2 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{std::move(*(last - $n$))} for the overload in namespace \tcode{std}, or +\item \tcode{ranges::iter_move(last - $n$)} for the overloads in namespace \tcode{ranges}. +\end{itemize} +Let $N$ be \tcode{last - first}. + \pnum \requires \tcode{result} @@ -2649,28 +4342,30 @@ \effects Moves elements in the range \range{first}{last} into the -range \range{result - (last-first)}{result} +range \range{result - $N$}{result} starting from \tcode{last - 1} -and proceeding to first.\footnote{\tcode{move_backward} +and proceeding to \tcode{first}.\footnote{\tcode{move_backward} should be used instead of move when last is in the range -\range{result - (last - first)}{result}.} +\range{result - $N$}{result}.} For each positive integer -\tcode{n <= (last - first)}, +$n \le N$, performs -\tcode{*(result - n) = std::move(*(last - n))}. +\tcode{*(result - $n$) = $E$}. \pnum \returns -\tcode{result - (last - first)}. +\begin{itemize} +\item \tcode{result - $N$} for the overload in namespace \tcode{std}, or +\item \tcode{\{last, result - $N$\}} for the overloads + in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Exactly $N$ assignments. \end{itemdescr} \rSec2[alg.swap]{Swap} @@ -2686,34 +4381,60 @@ swap_ranges(ExecutionPolicy&& exec, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item \tcode{last2} be \tcode{first2 + (last1 - first1)} for the overloads with + no parameter named \tcode{last2}, and +\item $M$ be $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$. +\end{itemize} + \pnum \requires The two ranges \range{first1}{last1} and -\range{first2}{first2 + (last1 - first1)} +\range{first2}{last2} shall not overlap. -\tcode{*(first1 + n)} shall be swappable with\iref{swappable.requirements} -\tcode{*(first2 + n)}. +For the overloads in namespace \tcode{std}, +\tcode{*(first1 + $n$)} shall be swappable with\iref{swappable.requirements} +\tcode{*(first2 + $n$)}. \pnum \effects -For each non-negative integer -\tcode{n < (last1 - first1)} +For each non-negative integer $n < M$ performs: -\tcode{swap(*(first1 + n), \brk{}*(first2 + n))}. +\begin{itemize} +\item \tcode{swap(*(first1 + $n$), *(first2 + $n$))} for the overloads in + namespace \tcode{std}, or +\item \tcode{ranges::iter_swap(first1 + $n$, first2 + $n$)} for the overloads + in namespace \tcode{ranges}. +\end{itemize} \pnum \returns -\tcode{first2 + (last1 - first1)}. +\begin{itemize} +\item \tcode{last2} for the overloads in namespace \tcode{std}, or +\item \tcode{\{first1 + $M$, first2 + $M$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last1 - first1} -swaps. +Exactly $M$ swaps. \end{itemdescr} \indexlibrary{\idxcode{iter_swap}}% @@ -2740,13 +4461,13 @@ template constexpr OutputIterator - transform(InputIterator first, InputIterator last, + transform(InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op); template ForwardIterator2 transform(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 result, UnaryOperation op); 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item \tcode{last2} be \tcode{first2 + (last1 - first1)} for the overloads with + parameter \tcode{first2} but no parameter \tcode{last2}, +\item $N$ be \tcode{last1 - first1} for unary transforms, or + $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ for binary transforms, and +\item $E$ be + \begin{itemize} + \item \tcode{op(*(first1 + (i - result)))} for unary transforms defined in + namespace \tcode{std}, + \item \tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))} for + binary transforms defined in namespace \tcode{std}, + \item \tcode{invoke(op, invoke(proj, *(first1 + (i - result))))} for unary + transforms defined in namespace \tcode{ranges}, or + \item \tcode{invoke(binary_op, invoke(proj1, *(first1 + (i - result))), invoke(proj2,\linebreak *(first2 + (i - result))))} + for binary transforms defined in namespace \tcode{ranges}. + \end{itemize} +\end{itemize} + \pnum \requires \tcode{op} and \tcode{binary_op} shall not invalidate iterators or subranges, or modify elements in the ranges \begin{itemize} -\item \crange{first1}{last1}, -\item \crange{first2}{first2 + (last1 - first1)}, and -\item \crange{result}{result + (last1 - first1)}.\footnote{The use of fully +\item \crange{first1}{first1 + $N$}, +\item \crange{first2}{first2 + $N$}, and +\item \crange{result}{result + $N$}.\footnote{The use of fully closed ranges is intentional.} \end{itemize} @@ -2781,31 +4551,31 @@ Assigns through every iterator \tcode{i} in the range -\range{result}{result + (last1 - first1)} +\range{result}{result + $N$} a new -corresponding value equal to -\tcode{op(*(first1 + (i - result)))} -or -\tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))}. +corresponding value equal to $E$. \pnum \returns -\tcode{result + (last1 - first1)}. +\begin{itemize} +\item \tcode{result + $N$} + for the overloads defined in namespace \tcode{std}, +\item \tcode{\{first1 + $N$, result + $N$\}} for unary transforms + defined in namespace \tcode{ranges}, or +\item \tcode{\{first1 + $N$, first2 + $N$, result + $N$\}} for binary + transforms defined in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last1 - first1} -applications of -\tcode{op} or \tcode{binary_op}. This requirement also applies to the overload +Exactly $N$ applications of +\tcode{op} or \tcode{binary_op}, and any projections. +This requirement also applies to the overload with an \tcode{ExecutionPolicy} . \pnum \remarks -\tcode{result} may be equal to \tcode{first} -in case of unary transform, -or to \tcode{first1} or \tcode{first2} -in case of binary transform. +\tcode{result} may be equal to \tcode{first1} or \tcode{first2}. \end{itemdescr} \rSec2[alg.replace]{Replace} @@ -2828,9 +4598,40 @@ void replace_if(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{bool(*i == old_value)} for \tcode{replace}, +\item \tcode{bool(pred(*i))} for \tcode{replace_if}, +\item \tcode{bool(invoke(proj, *i) == old_value)} for \tcode{ranges::replace}, or +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::replace_if}. +\end{itemize} + \pnum \requires The expression @@ -2843,14 +4644,17 @@ \tcode{i} in the range \range{first}{last} with \tcode{new_value}, -when the following corresponding conditions hold: -\tcode{*i == old_value}, \tcode{pred(*i) != false}. +when $E$ is \tcode{true}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity Exactly \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \end{itemdescr} \indexlibrary{\idxcode{replace_copy}}% @@ -2880,9 +4684,53 @@ ForwardIterator1 first, ForwardIterator1 last, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\setlength{\emergencystretch}{1.5em} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{bool(*(first + (i - result)) == old_value)} + for \tcode{replace_copy}, +\item \tcode{bool(pred(*(first + (i - result))))} + for \tcode{replace_copy_if}, +\item \tcode{bool(invoke(proj, *(first + (i - result))) == old_value)} + for \tcode{ranges::replace_copy}, +\item \tcode{bool(invoke(pred, invoke(proj, *(first + (i - result)))))} + for \tcode{ranges::replace_\-copy_if}. +\end{itemize} + \pnum \requires The results of the expressions @@ -2909,22 +4757,22 @@ \tcode{new_value} or \tcode{*\brk(first + (i - result))} -depending on whether the following corresponding conditions hold: - -\begin{codeblock} -*(first + (i - result)) == old_value -pred(*(first + (i - result))) != false -\end{codeblock} +depending on whether $E$ holds. \pnum \returns -\tcode{result + (last - first)}. +\begin{itemize} +\item \tcode{result + (last - first)} for the overloads in + namespace \tcode{std}, or +\item \tcode{\{last, result + (last - first)\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity Exactly \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \end{itemdescr} \rSec2[alg.fill]{Fill} @@ -2944,9 +4792,22 @@ ForwardIterator fill_n(ExecutionPolicy&& exec, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be $\max(0, \tcode{n})$ for the \tcode{fill_n} algorithms, and +\tcode{last - first} for the \tcode{fill} algorithms. + \pnum \requires The expression @@ -2957,20 +4818,14 @@ \pnum \effects -The \tcode{fill} algorithms assign \tcode{value} through all the iterators in the range -\range{first}{last}. The \tcode{fill_n} algorithms assign \tcode{value} -through all the iterators in the range \range{first}{first + n} -if \tcode{n} is positive, otherwise they do nothing. +Assigns \tcode{value} through all the iterators in the range \range{first}{first + $N$}. \pnum -\returns \tcode{fill_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +\returns \tcode{first + $N$}. \pnum \complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 assignments, respectively. +Exactly $N$ assignments. \end{itemdescr} \rSec2[alg.generate]{Generate} @@ -2991,34 +4846,42 @@ template 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be $\max(0, \tcode{n})$ for the \tcode{generate_n} algorithms, and +\tcode{last - first} for the \tcode{generate} algorithms. + \pnum \requires -\tcode{gen} takes no arguments, \tcode{Size} shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). \pnum \effects -The \tcode{generate} algorithms invoke the function object \tcode{gen} and assign the return -value of \tcode{gen} through all the iterators in the range -\range{first}{last}. The \tcode{generate_n} algorithms invoke the function object -\tcode{gen} and assign the return value of \tcode{gen} through all the iterators in -the range \range{first}{first + n} if \tcode{n} is positive, -otherwise they do nothing. +Assigns the result of successive evaluations of \tcode{gen()} +through each iterator in the range \range{first}{first + $N$}. \pnum -\returns \tcode{generate_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +\returns +\tcode{first + $N$}. \pnum \complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 -invocations of \tcode{gen} and assignments, respectively. +Exactly $N$ evaluations of \tcode{gen()} and assignments. \end{itemdescr} \rSec2[alg.remove]{Remove} @@ -3041,14 +4904,42 @@ ForwardIterator remove_if(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{bool(*i == value)} for \tcode{remove}, +\item \tcode{bool(pred(*i))} for \tcode{remove_if}, +\item \tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::remove}, or +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::remove_if}. +\end{itemize} + \pnum \requires -The type of +For the algorithms in namespace \tcode{std}, the type of \tcode{*first} -shall satisfy the \oldconcept{MoveAssignable} +shall meet the \oldconcept{MoveAssignable} requirements (\tref{moveassignable}). \pnum @@ -3056,8 +4947,7 @@ Eliminates all the elements referred to by iterator \tcode{i} in the range \range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == value, pred(*i) != false}. +for which $E$ holds. \pnum \returns @@ -3070,7 +4960,7 @@ \complexity Exactly \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \pnum \begin{note} @@ -3105,9 +4995,45 @@ remove_copy_if(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $E$ be +\begin{itemize} +\item \tcode{bool(*i == value)} for \tcode{remove_copy}, +\item \tcode{bool(pred(*i))} for \tcode{remove_copy_if}, +\item \tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::remove_copy}, or +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::remove_copy_if}. +\end{itemize} + +\pnum +Let $N$ be the number of elements in \range{first}{last} for which $E$ is \tcode{false}. + \pnum \requires The ranges @@ -3117,8 +5043,8 @@ shall not overlap. The expression \tcode{*result = *first} shall be valid. \begin{note} For the overloads with an \tcode{ExecutionPolicy}, there may be a performance -cost if \tcode{iterator_traits::value_type} is not -\oldconcept{\-Move\-Constructible} (\tref{moveconstructible}). +cost if \tcode{iterator_traits::value_type} does not meet the +\oldconcept{\-Move\-Constructible} (\tref{moveconstructible}) requirements. \end{note} \pnum @@ -3127,18 +5053,20 @@ \tcode{i} in the range \range{first}{last} -for which the following corresponding conditions do not hold: -\tcode{*i == value, pred(*i) != false}. +for which $E$ is \tcode{false}. \pnum \returns -The end of the resulting range. +\begin{itemize} +\item \tcode{result + $N$}, for the algorithms in namespace \tcode{std}, or +\item \tcode{\{last, result + $N$\}}, for the algorithms in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity Exactly \tcode{last - first} -applications of the corresponding predicate. +applications of the corresponding predicate and any projection. \pnum \remarks Stable\iref{algorithm.stable}. @@ -3161,13 +5089,36 @@ ForwardIterator unique(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{pred} be \tcode{equal_to\{\}} for the overloads with no +parameter \tcode{pred}, and let $E$ be +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item \tcode{bool(pred(*(i - 1), *i))} + for the overloads in namespace \tcode{std}, or +\item \tcode{bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + \pnum \requires -The comparison function shall be an equivalence relation. -The type of \tcode{*first} shall satisfy the +For the overloads in namepace \tcode{std}, +\tcode{pred} shall be an equivalence relation and +the type of \tcode{*first} shall meet the \oldconcept{MoveAssignable} requirements (\tref{moveassignable}). \pnum @@ -3177,10 +5128,7 @@ \tcode{i} in the range \range{first + 1}{last} -for which the following conditions hold: -\tcode{*(i - 1) == *i} -or -\tcode{pred(*(i - 1), *i) != false}. +for which $E$ is \tcode{true}. \pnum \returns @@ -3190,7 +5138,8 @@ \complexity For nonempty ranges, exactly \tcode{(last - first) - 1} -applications of the corresponding predicate. +applications of the corresponding predicate +and no more than twice as many applications of any projection. \end{itemdescr} \indexlibrary{\idxcode{unique_copy}}% @@ -3216,16 +5165,42 @@ unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); -\end{itemdecl} +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 = {}); +} +\end{itemdecl} \begin{itemdescr} \pnum -\requires +Let \tcode{pred} be \tcode{equal_to\{\}} for the overloads in +namespace \tcode{std} with no parameter \tcode{pred}, and let $E$ be \begin{itemize} -\item -The comparison function shall be an equivalence relation. +\setlength{\emergencystretch}{1em} +\item \tcode{bool(pred(*i, *(i - 1)))} + for the overloads in namespace \tcode{std}, or +\item \tcode{bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} +\pnum +\requires +\begin{itemize} \item The ranges \range{first}{last} @@ -3233,6 +5208,12 @@ \range{result}{result+(last-first)} shall not overlap. +\item +For the overloads in namespace \tcode{std}: +\begin{itemize} +\item +The comparison function shall be an equivalence relation. + \item The expression \tcode{*result = *first} @@ -3245,15 +5226,16 @@ then there are no additional requirements for \tcode{T}. Otherwise, if \tcode{OutputIterator} meets the \oldconcept{ForwardIterator} requirements and its value type is the same as \tcode{T}, -then \tcode{T} shall be \oldconcept{CopyAssignable} (\tref{copyassignable}). -Otherwise, \tcode{T} shall be both -\oldconcept{CopyConstructible} (\tref{copyconstructible}) and \oldconcept{CopyAssignable}. +then \tcode{T} shall meet the \oldconcept{CopyAssignable} (\tref{copyassignable}) requirements. +Otherwise, \tcode{T} shall meet both the +\oldconcept{CopyConstructible} (\tref{copyconstructible}) and \oldconcept{CopyAssignable} requirements. \begin{note} For the overloads with an \tcode{ExecutionPolicy}, there may be a performance -cost if the value type of \tcode{ForwardIterator1} is not both -\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable}. +cost if the value type of \tcode{ForwardIterator1} dos not meet both the +\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} requirements. \end{note} \end{itemize} +\end{itemize} \pnum \effects @@ -3262,20 +5244,21 @@ \tcode{i} in the range \range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == *(i - 1)} -or -\tcode{pred(*i, *(i - 1)) != false}. +for which $E$ holds. \pnum \returns -The end of the resulting range. +\begin{itemize} +\item \tcode{result + $N$} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last, result + $N$\}} for the overloads in namespace \tcode{ranges} +\end{itemize} \pnum \complexity -For nonempty ranges, exactly +Exactly \tcode{last - first - 1} -applications of the corresponding predicate. +applications of the corresponding predicate +and no more than twice as many applications of any projectionh. \end{itemdescr} \rSec2[alg.reverse]{Reverse} @@ -3287,23 +5270,38 @@ template 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); +} \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. \pnum \effects For each non-negative integer \tcode{i < (last - first) / 2}, applies -\tcode{iter_swap} +\tcode{std::iter_swap}, or +\tcode{ranges::\brk{}iter_swap} for the overloads in namespace \tcode{ranges}, to all pairs of iterators \tcode{first + i, (last - i) - 1}. +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + \pnum \complexity Exactly @@ -3322,15 +5320,29 @@ reverse_copy(ExecutionPolicy&& exec, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + \pnum \requires The ranges \range{first}{last} and -\range{result}{result + (last - first)} +\range{result}{result + $N$} shall not overlap. \pnum @@ -3338,22 +5350,26 @@ Copies the range \range{first}{last} to the range -\range{result}{result + (last - first)} +\range{result}{result + $N$} such that for every non-negative integer -\tcode{i < (last - first)} +\tcode{i < $N$} the following assignment takes place: -\tcode{*(result + (last - first) - 1 - i) = *(first + i)}. +\tcode{*(result + $N$ - 1 - i) = *(first + i)}. \pnum \returns -\tcode{result + (last - first)}. +\begin{itemize} +\item +\tcode{result + $N$} for the overloads in namespace \tcode{std}, or +\item +\tcode{\{last, result + $N$\}} for the overloads + in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Exactly $N$ assignments. \end{itemdescr} \rSec2[alg.rotate]{Rotate} @@ -3367,6 +5383,11 @@ ForwardIterator rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last); + +namespace ranges { + template S> + constexpr subrange rotate(I first, I middle, S last); +} \end{itemdecl} \begin{itemdescr} @@ -3376,8 +5397,10 @@ and \range{middle}{last} shall be valid ranges. -\tcode{ForwardIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type of \tcode{*first} shall satisfy +For the overloads in namespace \tcode{std}, +\tcode{ForwardIterator} shall meet the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}, and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. @@ -3389,13 +5412,18 @@ \tcode{first + i} into position \tcode{first + (i + (last - middle)) \% (last - first)}. +\begin{note} +This is a left rotate. +\end{note} \pnum -\returns \tcode{first + (last - middle)}. - -\pnum -\remarks -This is a left rotate. +\returns +\begin{itemize} +\item \tcode{first + (last - middle)} for the overloads in + namespace \tcode{std}, or +\item \tcode{\{first + (last - middle), last\}} for the overload in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity @@ -3404,6 +5432,20 @@ swaps. \end{itemdescr} +\begin{itemdecl} +namespace ranges { + template + requires Permutable> + constexpr safe_subrange_t rotate(R&& r, iterator_t middle); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return ranges::rotate(ranges::begin(r), middle, ranges::end(r));} +\end{itemdescr} + \indexlibrary{\idxcode{rotate_copy}}% \begin{itemdecl} template @@ -3415,15 +5457,29 @@ rotate_copy(ExecutionPolicy&& exec, 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); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + \pnum \requires +\range{first}{middle} +and +\range{middle}{last} +shall be valid ranges. The ranges \range{first}{last} and -\range{result}{result + (last - first)} +\range{result}{result + $N$} shall not overlap. \pnum @@ -3431,22 +5487,43 @@ Copies the range \range{first}{last} to the range -\range{result}{result + (last - first)} +\range{result}{result + $N$} such that for each non-negative integer -\tcode{i < (last - first)} +$i < N$ the following assignment takes place: -\tcode{*(result + i) = *(first + -(i + (middle - first)) \% (last - first))}. +\tcode{*(result + $i$) = *(first + +($i$ + (middle - first)) \% $N$)}. \pnum \returns -\tcode{result + (last - first)}. +\begin{itemize} +\item +\tcode{result + $N$} for the overloads in namespace \tcode{std}, or +\item +\tcode{\{last, result + $N$\}} for the overload in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Exactly $N$ assignments. +\end{itemdescr} + +\begin{itemdecl} +namespace ranges { + template + requires IndirectlyCopyable, O> + constexpr rotate_copy_result, O> + rotate_copy(R&& r, iterator_t middle, O result); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return ranges::rotate_copy(ranges::begin(r), middle, ranges::end(r), result); +\end{codeblock} \end{itemdescr} \rSec2[alg.random.sample]{Sample} @@ -3485,7 +5562,7 @@ \pnum \effects -Copies \tcode{min(last - first, n)} elements (the \defn{sample}) +Copies $\min(\tcode{last - first}, \ \tcode{n})$ elements (the \defn{sample}) from \range{first}{last} (the \defn{population}) to \tcode{out} such that each possible sample has equal probability of appearance. \begin{note} @@ -3522,19 +5599,33 @@ void shuffle(RandomAccessIterator first, 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); +} \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the +For the overload in namespace \tcode{std}: +\begin{itemize} +\item +\tcode{RandomAccessIterator} shall meet the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +\item The type \tcode{remove_reference_t} -shall satisfy the requirements of a -uniform random bit generator\iref{rand.req.urng} type whose return type is -convertible to -\tcode{iterator_traits::difference_type}. +shall meet the +uniform random bit generator\iref{rand.req.urng} requirements. +\end{itemize} \pnum \effects @@ -3542,6 +5633,10 @@ \range{first}{last} such that each possible permutation of those elements has equal probability of appearance. +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + \pnum \complexity Exactly @@ -3551,7 +5646,7 @@ \pnum \remarks To the extent that the implementation of this function makes use of random -numbers, the object \tcode{g} shall serve as the implementation's source of +numbers, the object referenced by \tcode{g} shall serve as the implementation's source of randomness. \end{itemdescr} @@ -3643,7 +5738,8 @@ \rSec1[alg.sorting]{Sorting and related operations} \pnum -All the operations in~\ref{alg.sorting} have two versions: one that takes a function object of type +The operations in~\ref{alg.sorting} defined directly in namespace \tcode{std} +have two versions: one that takes a function object of type \tcode{Compare} and one that uses an \tcode{operator<}. @@ -3651,7 +5747,10 @@ \pnum \tcode{Compare} is a function object -type\iref{function.objects}. The return value of the function call operation applied to +type\iref{function.objects} +that meets the requirements for a template parameter named +\tcode{BinaryPredicate}~\iref{algorithms.requirements}. +The return value of the function call operation applied to an object of type \tcode{Compare}, when contextually converted to \tcode{bool}\iref{conv}, yields \tcode{true} if the first argument of the call @@ -3660,9 +5759,6 @@ otherwise. \tcode{Compare comp} is used throughout for algorithms assuming an ordering relation. -It is assumed that -\tcode{comp} -will not apply any non-constant function through the dereferenced iterator. \pnum For all algorithms that take @@ -3726,15 +5822,19 @@ \pnum A sequence is -\term{sorted with respect to a comparator} -\tcode{comp} if for every iterator +\term{sorted with respect to a \tcode{comp} and \tcode{proj}} +for a comparator and projection \tcode{comp} and \tcode{proj} +if for every iterator \tcode{i} pointing to the sequence and every non-negative integer \tcode{n} such that \tcode{i + n} is a valid iterator pointing to an element of the sequence, -\tcode{comp(*(i + n), *i) == false}. +\begin{codeblock} +bool(invoke(comp, invoke(proj, *(i + n)), invoke(proj, *i))) +\end{codeblock} +is \tcode{false}. \pnum A sequence @@ -3782,25 +5882,48 @@ void sort(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects Sorts the elements in the range -\range{first}{last}. +\range{first}{last} with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last}, for the overloads in namespace \tcode{ranges}. \pnum \complexity -\bigoh{N \log N} comparisons, where $N = \tcode{last - first}$. +Let $N$ be \tcode{last - first}. +\bigoh{N \log N} comparisons and projections. \end{itemdescr} \rSec3[stable.sort]{\tcode{stable_sort}} @@ -3820,26 +5943,50 @@ void stable_sort(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Sorts the elements in the range \range{first}{last}. +Sorts the elements in the range \range{first}{last} +with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity -At most $N \log^2(N)$ -comparisons, where -$N = \tcode{last - first}$, but only $N \log N$ comparisons if there is enough extra memory. +Let $N$ be \tcode{last - first}. +If enough extra memory is available, $N \log(N)$ comparisons. +Otherwise, at most $N \log^2(N)$ comparisons. +In either case, twice as many projections as +the number of comparisons. \pnum \remarks Stable\iref{algorithm.stable}. @@ -3871,14 +6018,28 @@ 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +\range{first}{middle} and \range{middle}{last} shall be valid ranges. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. @@ -3886,8 +6047,8 @@ \effects Places the first \tcode{middle - first} -sorted elements from the range -\range{first}{last} +elements from the range +\range{first}{last} as sorted with respect to \tcode{comp} and \tcode{proj} into the range \range{first}{middle}. The rest of the elements in the range @@ -3895,11 +6056,32 @@ are placed in an unspecified order. \indextext{unspecified}% +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. + \pnum \complexity Approximately \tcode{(last - first) * log(middle - first)} -comparisons. +comparisons, and twice as many projections. +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return ranges::partial_sort(ranges::begin(r), middle, ranges::end(r), comp, proj); +\end{codeblock} \end{itemdescr} \rSec3[partial.sort.copy]{\tcode{partial_sort_copy}} @@ -3933,35 +6115,77 @@ RandomAccessIterator result_first, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result_first})$. +Let \tcode{comp} be \tcode{less\{\}}, and +\tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*result_first} shall satisfy the +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}, +the type of \tcode{*result_first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and -\oldconcept{\-Move\-Assignable} (\tref{moveassignable}) requirements. +\oldconcept{\-Move\-Assignable} (\tref{moveassignable}) requirements, +and the expression \tcode{*first} +shall be writable\iref{iterator.requirements.general} to \tcode{result_first}. + +\pnum +\expects +For iterators \tcode{a1} and \tcode{b1} in \range{first}{last}, and +iterators \tcode{x2} and \tcode{y2} in \range{result_first}{result_last}, +after evaluating the assignment \tcode{*y2 = *b1}, let $E$ be the value of +\begin{codeblock} +bool(invoke(comp, invoke(proj1, *a1), invoke(proj2, *y2))). +\end{codeblock} +Then, after evaluating the assignment \tcode{*x2 = *a1}, +$E$ is equal to +\begin{codeblock} +bool(invoke(comp, invoke(proj2, *x2), invoke(proj2, *y2))). +\end{codeblock} +\begin{note} +Writing a value from the input range into the output range does not affect +how it is ordered by \tcode{comp} and \tcode{proj1} or \tcode{proj2}. +\end{note} \pnum \effects -Places the first -\tcode{min(last - first, result_last - result_first)} -sorted elements into the range -\range{result_first}{result_first + min(last - first, result_last - result_first)}. +Places the first $N$ elements +as sorted with respect to \tcode{comp} and \tcode{proj2} into the range +\range{result_first}{result_first + $N$}. \pnum \returns -The smaller of: -\tcode{result_last} or -\tcode{result_first + (last - first)}. +\tcode{result_first + $N$}. \pnum \complexity -Approximately -\tcode{(last - first) * log(min(last - first, result_last - result_first))} -comparisons. +Approximately \tcode{(last - first) * log $N$} comparisons, +and twice as many projections. \end{itemdescr} \rSec3[is.sorted]{\tcode{is_sorted}} @@ -3974,7 +6198,8 @@ \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last) == last}. +\effects +Equivalent to: return \tcode{is_sorted_until(first, last) == last;} \end{itemdescr} \indexlibrary{\idxcode{is_sorted}}% @@ -3986,10 +6211,13 @@ \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(std::forward(exec), first, last) == last}. +\effects +Equivalent to: +\begin{codeblock} +return is_sorted_until(std::forward(exec), first, last) == last; +\end{codeblock} \end{itemdescr} - \indexlibrary{\idxcode{is_sorted}}% \begin{itemdecl} template @@ -3999,7 +6227,8 @@ \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last, comp) == last}. +\effects +Equivalent to: \tcode{return is_sorted_until(first, last, comp) == last;} \end{itemdescr} @@ -4013,12 +6242,30 @@ \begin{itemdescr} \pnum -\returns +\effects +Equivalent to: \begin{codeblock} is_sorted_until(std::forward(exec), first, last, comp) == last \end{codeblock} \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return ranges::is_sorted_until(first, last, comp, proj) == last;} +\end{itemdescr} \indexlibrary{\idxcode{is_sorted_until}}% \begin{itemdecl} @@ -4039,15 +6286,28 @@ is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); -\end{itemdecl} +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 = {}); +} +\end{itemdecl} \begin{itemdescr} \pnum -\returns If \tcode{(last - first) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is sorted. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\returns +The last iterator \tcode{i} in \crange{first}{last} for which the +range \range{first}{i} is sorted with respect to \tcode{comp} and \tcode{proj}. \pnum \complexity Linear. @@ -4072,14 +6332,29 @@ void nth_element(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +\range{first}{nth} and \range{nth}{last} shall be valid ranges. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}, and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. @@ -4089,7 +6364,9 @@ \tcode{nth_element} the element in the position pointed to by \tcode{nth} is the element that would be -in that position if the whole range were sorted, unless \tcode{nth == last}. +in that position +if the whole range were sorted with respect to \tcode{comp} and \tcode{proj}, +unless \tcode{nth == last}. Also for every iterator \tcode{i} in the range @@ -4099,9 +6376,12 @@ in the range \range{nth}{last} it holds that: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. +\tcode{bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))} +is \tcode{false}. + +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. \pnum \complexity @@ -4110,13 +6390,30 @@ the predicate, and \bigoh{N \log N} swaps, where $N = \tcode{last - first}$. \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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return ranges::nth_element(ranges::begin(r), nth, ranges::end(r), comp, proj); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.binary.search]{Binary search} \pnum All of the algorithms in this subclause are versions of binary search and assume that the sequence being searched is partitioned with respect to an expression formed by binding the search key to an argument of the -implied or explicit comparison function. +comparison function. They work on non-random access iterators minimizing the number of comparisons, which will be logarithmic for all types of iterators. They are especially appropriate for random access iterators, @@ -4137,9 +6434,26 @@ constexpr ForwardIterator 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires The elements @@ -4147,9 +6461,7 @@ of \range{first}{last} shall be partitioned with respect to the expression -\tcode{e < value} -or -\tcode{comp(e, value)}. +\tcode{bool(invoke(comp, invoke(proj, e), value))}. \pnum \returns @@ -4160,17 +6472,14 @@ such that for every iterator \tcode{j} in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{*j < value} -or -\tcode{comp(*j, value) != false}. +\range{first}{i}, +\tcode{bool(invoke(comp, invoke(proj, *j), value))} is \tcode{true}. \pnum \complexity At most $\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +comparisons and projections. \end{itemdescr} \rSec3[upper.bound]{\tcode{upper_bound}} @@ -4186,9 +6495,25 @@ constexpr ForwardIterator 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires The elements @@ -4196,9 +6521,7 @@ of \range{first}{last} shall be partitioned with respect to the expression -\tcode{!(value < e)} -or -\tcode{!comp(\brk{}value, e)}. +\tcode{!bool(invoke(comp, value, invoke(proj, e)))}. \pnum \returns @@ -4209,17 +6532,14 @@ such that for every iterator \tcode{j} in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{!(value < *j)} -or -\tcode{comp(value, *j) == false}. +\range{first}{i}, +\tcode{!bool(invoke(comp, value, invoke(proj, *j)))} is \tcode{true}. \pnum \complexity At most $\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +comparisons and projections. \end{itemdescr} \rSec3[equal.range]{\tcode{equal_range}} @@ -4236,9 +6556,26 @@ equal_range(ForwardIterator first, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires The elements @@ -4246,42 +6583,36 @@ of \range{first}{last} shall be partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} +\tcode{bool(invoke(comp, invoke(proj, e), value))} and -\tcode{!comp(value, e)}. +\tcode{!bool(invoke(comp, value, invoke(proj, e)))}. Also, for all elements \tcode{e} of \tcode{[first, last)}, -\tcode{e < value} -shall imply -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -shall imply -\tcode{!comp(value, e)}. +\tcode{bool(comp(e, value))} shall imply \tcode{!bool(comp(\brk{}value, e))} +for the overloads in namespace \tcode{std}. \pnum \returns +\begin{itemize} +\item +For the overloads in namespace \tcode{std}: \begin{codeblock} -make_pair(lower_bound(first, last, value), - upper_bound(first, last, value)) -\end{codeblock} -or -\begin{codeblock} -make_pair(lower_bound(first, last, value, comp), - upper_bound(first, last, value, comp)) +\{lower_bound(first, last, value, comp), + upper_bound(first, last, value, comp)\} \end{codeblock} +\item +For the overloads in namespace \tcode{ranges}: +\{ranges::lower_bound(first, last, value, comp, proj), + ranges::upper_bound(first, last, value, comp, proj)\} +\end{itemize} \pnum \complexity At most $2 * \log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +comparisons and projections. \end{itemdescr} \rSec3[binary.search]{\tcode{binary_search}} @@ -4297,9 +6628,26 @@ constexpr bool 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires The elements @@ -4307,42 +6655,31 @@ of \range{first}{last} shall be partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -and -\tcode{!comp(value, e)}. +\tcode{bool(invoke(comp, invoke(proj, e), value))} and +\tcode{!bool(invoke(comp, value, invoke(proj, e)))}. Also, for all elements \tcode{e} of \tcode{[first, last)}, -\tcode{e < value} +\tcode{bool(comp(e, value))} shall imply -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -shall imply -\tcode{!comp(value, e)}. +\tcode{!bool(comp(\brk{}value, e))} +for the overloads in namespace \tcode{std}. \pnum \returns \tcode{true} -if there is an iterator +if and only if for some iterator \tcode{i} in the range -\range{first}{last} -that satisfies the corresponding conditions: -\tcode{!(*i < value) \&\& !(value < *i)} -or -\tcode{comp(*i, value) == false \&\& comp(value, *i) == false}. +\range{first}{last}, +\tcode{!bool(invoke(comp, invoke(proj, *i), value)) \&\& !bool(invoke(comp, value, invoke(proj, *i)))} is \tcode{true}. \pnum \complexity At most $\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +comparisons and projections. \end{itemdescr} \rSec2[alg.partitions]{Partitions} @@ -4354,25 +6691,31 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires For the overload with no \tcode{ExecutionPolicy}, -\tcode{InputIterator}'s value type shall be convertible to \tcode{Predicate}'s -argument type. For the overload with an \tcode{ExecutionPolicy}, -\tcode{ForwardIterator}'s value type shall be convertible to \tcode{Predicate}'s -argument type. +Let \tcode{proj} be \tcode{identity\{\}} for +the overloads with no parameter named \tcode{proj}. \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if +\returns \tcode{true} if and only if the elements \tcode{e} of \range{first}{last} are partitioned with respect to the expression -\tcode{pred(e)}. +\tcode{bool(invoke(pred, invoke(proj, e)))}. \pnum -\complexity Linear. At most \tcode{last - first} applications of \tcode{pred}. +\complexity Linear. At most \tcode{last - first} applications of \tcode{pred} +and \tcode{proj}. \end{itemdescr} \indexlibrary{\idxcode{partition}}% @@ -4384,28 +6727,52 @@ ForwardIterator 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} for the overloads +with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + \pnum \requires -\tcode{ForwardIterator} shall satisfy the +For the overloads in namespace \tcode{std}, +\tcode{ForwardIterator} shall meet the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. \pnum -\effects Places all the elements in the range \range{first}{last} that satisfy \tcode{pred} before all the elements that do not satisfy it. +\effects Places all the elements \tcode{e} in \range{first}{last} +that satisfy $E(\tcode{e})$ before all the elements that do not. \pnum -\returns An iterator \tcode{i} such that for every iterator \tcode{j} in the range -\range{first}{i} \tcode{pred(*j) != false}, and for every iterator \tcode{k} in the -range \range{i}{last}, \tcode{pred(*k) == false}. +\returns An iterator \tcode{i} such that $E(\tcode{*j})$ is \tcode{true} +for every iterator \tcode{j} in +\range{first}{i} and \tcode{false} for every iterator \tcode{j} in +\range{i}{last}. \pnum \complexity Let $N = \tcode{last - first}$: \begin{itemize} \item For the overload with no \tcode{ExecutionPolicy}, exactly $N$ applications -of the predicate. At most $N / 2$ swaps if \tcode{ForwardIterator} meets the -\oldconcept{BidirectionalIterator} requirements and at most $N$ swaps otherwise. +of the predicate and projection. At most $N / 2$ swaps if the type of \tcode{first} meets the +\oldconcept{BidirectionalIterator} requirements +for the overloads in namespace \tcode{std} or +models \libconcept{BidirectionalIterator} for the +overloads in namespace \tcode{ranges}, +and at most $N$ swaps otherwise. \item For the overload with an \tcode{ExecutionPolicy}, \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. \end{itemize} @@ -4421,23 +6788,40 @@ BidirectionalIterator 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum +\pnum +Let \tcode{proj} be \tcode{identity\{\}} for the overloads +with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + \requires -\tcode{BidirectionalIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Places all the elements in the range -\range{first}{last} -that satisfy \tcode{pred} before all the -elements that do not satisfy it. +Places all the elements \tcode{e} in \range{first}{last} +that satisfy $E(\tcode{e})$ before all the +elements that do not. +The relative order of the elements in both groups is preserved. \pnum \returns @@ -4445,23 +6829,22 @@ \tcode{i} such that for every iterator \tcode{j} -in the range +in \range{first}{i}, -\tcode{pred(*j) != false}, +$E(\tcode{*j})$ is \tcode{true}, and for every iterator -\tcode{k} +\tcode{j} in the range \range{i}{last}, -\tcode{pred(*k) == false}. -The relative order of the elements in both groups is preserved. +$E(\tcode{*j})$ is \tcode{false}, \pnum \complexity Let $N$ = \tcode{last - first}: \begin{itemize} -\item For the overload with no \tcode{ExecutionPolicy}, at most $N \log N$ swaps, +\item For the overloads with no \tcode{ExecutionPolicy}, at most $N \log N$ swaps, but only \bigoh{N} swaps if there is enough extra memory. Exactly $N$ -applications of the predicate. +applications of the predicate and projection. \item For the overload with an \tcode{ExecutionPolicy}, \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. \end{itemize} @@ -4481,41 +6864,60 @@ partition_copy(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires -\begin{itemize} -\item -For the overload with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s -value type shall be \oldconcept{\-Copy\-Assign\-able} (\tref{copyassignable}), -and shall be writable\iref{iterator.requirements.general} to the \tcode{out_true} -and \tcode{out_false} \tcode{Output\-Iter\-ator}s, and shall be convertible to -\tcode{Predicate}'s argument type. +Let \tcode{proj} be \tcode{identity\{\}} for the overloads +with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. -\item -For the overload with an \tcode{ExecutionPolicy}, \tcode{ForwardIterator}'s -value type shall be \oldconcept{\-Copy\-Assign\-able}, and shall be writable to the -\tcode{out_true} and \tcode{out_false} \tcode{ForwardIterator}s, and shall be -convertible to \tcode{Predicate}'s argument type. +\pnum +\requires +The input range and output ranges shall not overlap. +For the overloads in namespace \tcode{std}, +the expression \tcode{*first} shall be +writable\iref{iterator.requirements.general} to +\tcode{out_true} and \tcode{out_false}. \begin{note} -There may be a performance cost if \tcode{ForwardIterator}'s value type is not -\oldconcept{CopyConstructible}. +For the overload with an \tcode{ExecutionPolicy}, +there may be a performance cost if \tcode{first}'s value type +does not meet the \oldconcept{CopyConstructible} requirements. \end{note} -\item -For both overloads, the input range shall not overlap with either of the output ranges. -\end{itemize} - \pnum -\effects For each iterator \tcode{i} in \range{first}{last}, copies \tcode{*i} to the output range beginning with \tcode{out_true} if \tcode{pred(*i)} is \tcode{true}, or to the output range beginning with \tcode{out_false} otherwise. +\effects +For each iterator \tcode{i} in \range{first}{last}, copies \tcode{*i} to the output range beginning with \tcode{out_true} if \tcode{$E(\tcode{*i})$} is \tcode{true}, or to the output range beginning with \tcode{out_false} otherwise. \pnum -\returns A pair \tcode{p} such that \tcode{p.first} is the end of the output range beginning at \tcode{out_true} and \tcode{p.second} is the end of the output range beginning at \tcode{out_false}. +\returns +Let \tcode{o1} be the end of the output range beginning at \tcode{out_true}, +and \tcode{o2} the end of the output range beginning at \tcode{out_false}. +Returns +\begin{itemize} +\item \tcode{\{o1, o2\}} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last, o1, o2\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum -\complexity Exactly \tcode{last - first} applications of \tcode{pred}. +\complexity Exactly \tcode{last - first} applications of \tcode{pred} +and \tcode{proj}. \end{itemdescr} \indexlibrary{\idxcode{partition_point}}% @@ -4523,20 +6925,39 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} for the overloads +with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + \pnum \requires -\tcode{ForwardIterator}'s value type shall be convertible to -\tcode{Predicate}'s argument type. The elements \tcode{e} of \range{first}{last} -shall be partitioned with respect to the expression \tcode{pred(e)}. +The elements \tcode{e} of \range{first}{last} +shall be partitioned with respect to $E(\tcode{e})$. \pnum -\returns An iterator \tcode{mid} such that \tcode{all_of(first, mid, pred)} and \tcode{none_of(mid, last, pred)} are both \tcode{true}. +\returns +An iterator \tcode{mid} such that +$E(\tcode{*i})$ is \tcode{true} for all iterators \tcode{i} +in \range{first}{mid}, and +\tcode{false} for all iterators \tcode{i} in \range{mid}{last} \pnum -\complexity \bigoh{\log(\tcode{last - first})} applications of \tcode{pred}. +\complexity \bigoh{\log(\tcode{last - first})} applications of \tcode{pred} +and \tcode{proj}. \end{itemdescr} \rSec2[alg.merge]{Merge} @@ -4570,28 +6991,61 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let $N$ be \tcode{(last1 - first1) + (last2 - first2)}. +Let \tcode{comp} be \tcode{less\{\}}, +\tcode{proj1} be \tcode{identity\{\}}, and +\tcode{proj2} be \tcode{identity\{\}}, +for the overloads with no parameters by those names. + \pnum \requires The ranges \range{first1}{last1} and \range{first2}{last2} shall be -sorted with respect to \tcode{oper\-ator<} or \tcode{comp}. +sorted with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. The resulting range shall not overlap with either of the original ranges. \pnum \effects Copies all the elements of the two ranges \range{first1}{last1} and \range{first2}{last2} into the range \range{result}{result_last}, where \tcode{result_last} -is \tcode{result + (last1 - first1) + (last2 - first2)}, such that the resulting range satisfies -\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(re\-sult, result_last, comp)}, respectively. +is \tcode{result + $N$}. +If an element \tcode{a} precedes \tcode{b} in an input range, \tcode{a} is +copied into the output range before \tcode{b}. If \tcode{e1} is an element of +\range{first1}{last1} and \tcode{e2} of \range{first2}{last2}, \tcode{e2} is +copied into the output range before \tcode{e1} if and only if +\tcode{bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))} +is \tcode{true}. \pnum \returns -\tcode{result + (last1 - first1) + (last2 - first2)}. +\begin{itemize} +\item \tcode{result_last} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last1, last2, result_last\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum -\complexity Let $N = \tcode{(last1 - first1) + (last2 - first2)}$: +\complexity \begin{itemize} -\item For the overloads with no \tcode{ExecutionPolicy}, at most $N - 1$ comparisons. +\item For the overloads with no \tcode{ExecutionPolicy}, at most $N - 1$ comparisons +and applications of each projection. \item For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N} comparisons. \end{itemize} @@ -4620,16 +7074,29 @@ BidirectionalIterator first, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires -The ranges \range{first}{middle} and \range{middle}{last} shall be -sorted with respect to \tcode{operator<} or \tcode{comp}. -\tcode{BidirectionalIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +\range{first}{middle} and \range{middle}{last} shall be valid ranges +sorted with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. @@ -4641,34 +7108,42 @@ \range{middle}{last}, putting the result of the merge into the range \range{first}{last}. -The resulting range will be in non-decreasing order; -that is, for every iterator -\tcode{i} -in -\range{first}{last} -other than -\tcode{first}, -the condition -\tcode{*i < *(i - 1)} -or, respectively, -\tcode{comp(*i, *(i - 1))} -will be \tcode{false}. +The resulting range is sorted with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. \pnum \complexity Let $N = \tcode{last - first}$: \begin{itemize} -\item For the overloads with no \tcode{ExecutionPolicy}, if enough additional +\item For the overloads with no \tcode{ExecutionPolicy}, and if enough additional memory is available, exactly $N - 1$ comparisons. -\item For the overloads with no \tcode{ExecutionPolicy} if no additional -memory is available, \bigoh{N \log N} comparisons. -\item For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N \log N} comparisons. +\item Otherwise, \bigoh{N \log N} comparisons. \end{itemize} - +In either case, twice as many projections as comparisons. \pnum \remarks Stable\iref{algorithm.stable}. \end{itemdescr} +\begin{itemdecl} +namespace ranges { + template, class Proj = identity> + requires Sortable, Comp, Proj> + safe_iterator_t + inplace_merge(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return ranges::inplace_merge(ranges::begin(r), middle, ranges::end(r), comp, proj); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.set.operations]{Set operations on sorted structures} \pnum @@ -4705,26 +7180,51 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}}, +\tcode{proj1} be \tcode{identity\{\}}, and +\tcode{proj2} be \tcode{identity\{\}}, +for the overloads with no parameters by those names. + +\pnum +\requires +The ranges \range{first1}{last1} and \range{first2}{last2} +shall be sorted with respect to \tcode{comp} +and \tcode{proj1} or \tcode{proj2}, respectively. + \pnum \returns \tcode{true} -if \range{first2}{last2} is empty or -if every element in the range -\range{first2}{last2} -is contained in the range -\range{first1}{last1}. -Returns -\tcode{false} -otherwise. +if and only if \range{first2}{last2} is a subsequence of \range{first1}{last1}. +\begin{note} +A sequence $S$ is a subsequence of another sequence $T$ if $S$ can be obtained +from $T$ by removing some, all, or none of $T$'s elements and keeping the +remaining elements in the same order. +\end{note} \pnum \complexity At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +comparisons and applications of each projection. \end{itemdescr} \rSec3[set.union]{\tcode{set_union}} @@ -4758,11 +7258,35 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}}, +and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires +The ranges \range{first1}{last1} and \range{first2}{last2} shall be +sorted with respect to \tcode{comp} and +\tcode{proj1} or \tcode{proj2}, respectively. The resulting range shall not overlap with either of the original ranges. \pnum @@ -4772,20 +7296,28 @@ \pnum \returns -The end of the constructed range. +Let \tcode{result_last} be the end of the constructed range. +Returns +\begin{itemize} +\item \tcode{result_last} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last1, last2, result_last\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +comparisons and applications of each projection. \pnum -\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to +\remarks +Stable\iref{algorithm.stable}. +If \range{first1}{last1} contains $m$ elements that are equivalent to each other and \range{first2}{last2} contains $n$ elements that are equivalent -to them, then all $m$ elements from the first range shall be copied to the output -range, in order, and then $\max(n - m, 0)$ elements from the second range shall -be copied to the output range, in order. +to them, then all $m$ elements from the first range are copied to the output +range, in order, and then the final $\max(n - m, 0)$ elements from the second range are +copied to the output range, in order. \end{itemdescr} \rSec3[set.intersection]{\tcode{set_intersection}} @@ -4819,11 +7351,35 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}}, +and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires +The ranges \range{first1}{last1} and \range{first2}{last2} shall be +sorted with respect to \tcode{comp} and +\tcode{proj1} or \tcode{proj2}, respectively. The resulting range shall not overlap with either of the original ranges. \pnum @@ -4833,18 +7389,26 @@ \pnum \returns -The end of the constructed range. +Let \tcode{result_last} be the end of the constructed range. +Returns +\begin{itemize} +\item \tcode{result_last} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last1, last2, result_last\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +comparisons and applications of each projection. \pnum -\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to +\remarks +Stable\iref{algorithm.stable}. +If \range{first1}{last1} contains $m$ elements that are equivalent to each other and \range{first2}{last2} contains $n$ elements that are equivalent -to them, the first $\min(m, n)$ elements shall be copied from the first range +to them, the first $\min(m, n)$ elements are copied from the first range to the output range, in order. \end{itemdescr} @@ -4879,11 +7443,35 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}}, +and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires +The ranges \range{first1}{last1} and \range{first2}{last2} shall be +sorted with respect to \tcode{comp} and +\tcode{proj1} or \tcode{proj2}, respectively. The resulting range shall not overlap with either of the original ranges. \pnum @@ -4898,13 +7486,19 @@ \pnum \returns -The end of the constructed range. +Let \tcode{result_last} be the end of the constructed range. +Returns +\begin{itemize} +\item \tcode{result_last} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last1, result_last\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +comparisons and applications of each projection. \pnum \remarks @@ -4918,7 +7512,7 @@ $\max(m - n, 0)$ elements from \range{first1}{last1} -shall be copied to the output range. +is copied to the output range, in order. \end{itemdescr} \rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} @@ -4952,12 +7546,38 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}}, +and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires The resulting range shall not overlap with either of the original ranges. +The ranges \range{first1}{last1} and \range{first2}{last2} shall be +sorted with respect to \tcode{comp} and +\tcode{proj1} or \tcode{proj2}, respectively. +The resulting range shall not overlap with either of the original ranges. \pnum \effects @@ -4975,40 +7595,49 @@ \pnum \returns -The end of the constructed range. +Let \tcode{result_last} be the end of the constructed range. +Returns +\begin{itemize} +\item \tcode{result_last} for the overloads in namespace \tcode{std}, or +\item \tcode{\{last1, last2, result_last\}} for the overloads in + namespace \tcode{ranges}. +\end{itemize} \pnum \complexity At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +comparisons and applications of each projection. \pnum \remarks +Stable\iref{algorithm.stable}. If \range{first1}{last1} contains $m$ elements that are equivalent to each other and \range{first2}{last2} contains $n$ elements that are equivalent to them, then $|m - n|$ of those elements shall be copied to the output range: the last $m - n$ of these elements from \range{first1}{last1} if $m > n$, and the last $n - m$ of these elements from \range{first2}{last2} if $m < n$. +In either case, the elements are copied in order. \end{itemdescr} \rSec2[alg.heap.operations]{Heap operations} \pnum -A -\term{heap} -is a particular organization of elements in a range between two random access iterators -\range{a}{b} such that: +A random access range \range{a}{b} is a +\defnx{heap with respect to \tcode{comp} and \tcode{proj}} +{heap with respect to comp and proj@heap with respect to \tcode{comp} and \tcode{proj}} +for a comparator and projection \tcode{comp} and \tcode{proj} +if its elements are organized such that: \begin{itemize} \item With \tcode{$N$ = b - a}, for all $i$, $0 < i < N$, -\tcode{comp(a[$\left \lfloor{\frac{i - 1}{2}}\right \rfloor$], a[$i$])} +\tcode{bool(invoke(comp, invoke(proj, a[$\left \lfloor{\frac{i - 1}{2}}\right \rfloor$]), invoke(\brk{}proj, a[$i$])))} is \tcode{false}. \item \tcode{*a} may be removed by -\tcode{pop_heap()}, +\tcode{pop_heap}, or a new element added by -\tcode{push_heap()}, +\tcode{push_heap}, in \bigoh{\log N} time. @@ -5018,9 +7647,9 @@ These properties make heaps useful as priority queues. \pnum -\tcode{make_heap()} +\tcode{make_heap} converts a range into a heap and -\tcode{sort_heap()} +\tcode{sort_heap} turns a heap into a sorted sequence. \rSec3[push.heap]{\tcode{push_heap}} @@ -5033,15 +7662,33 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires The range \range{first}{last - 1} -shall be a valid heap. -The type of \tcode{*first} shall satisfy +shall be a valid heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +the type of \tcode{*first} shall meet the \oldconcept{MoveConstructible} requirements (\tref{moveconstructible}) and the \oldconcept{MoveAssignable} requirements @@ -5054,11 +7701,15 @@ into the resulting heap \range{first}{last}. +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + \pnum \complexity At most $\log(\tcode{last - first})$ -comparisons. +comparisons and twice as many projections. \end{itemdescr} \rSec3[pop.heap]{\tcode{pop_heap}} @@ -5071,21 +7722,38 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \requires The range \range{first}{last} -shall be a valid non-empty heap. -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +shall be a valid non-empty heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall met the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. - \pnum \effects Swaps the value in the location \tcode{first} @@ -5093,13 +7761,17 @@ \tcode{last - 1} and makes \range{first}{last - 1} -into a heap. +into a heap with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity At most $2 \log(\tcode{last - first})$ -comparisons. +comparisons and twice as many projections. \end{itemdescr} \rSec3[make.heap]{\tcode{make_heap}} @@ -5112,26 +7784,49 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires The type of \tcode{*first} shall satisfy -the \oldconcept{MoveConstructible} requirements -(\tref{moveconstructible}) and the -\oldconcept{MoveAssignable} requirements -(\tref{moveassignable}). +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\requires +For the overloads in namespace \tcode{std}, +the type of \tcode{*first} shall meet +the \oldconcept{Move\-Constructible} +(\tref{moveconstructible}) and +\oldconcept{MoveAssignable} +(\tref{moveassignable}) requirements. \pnum \effects -Constructs a heap out of the range +Constructs a heap with respect to \tcode{comp} and \tcode{proj} out of the range \range{first}{last}. +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + \pnum \complexity At most $3(\tcode{last - first})$ -comparisons. +comparisons and twice as many projections. \end{itemdescr} \rSec3[sort.heap]{\tcode{sort_heap}} @@ -5144,27 +7839,51 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires The range \range{first}{last} shall be a valid heap. -\tcode{RandomAccessIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\requires +The range \range{first}{last} shall be +a valid heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} shall meet the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} shall meet the \oldconcept{MoveConst\-ruct\-ible} (\tref{moveconstructible}) and \oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects Sorts elements in the heap -\range{first}{last}. +\range{first}{last} with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity At most $2N \log N$ comparisons, where -$N = \tcode{last - first}$. +$N = \tcode{last - first}$, and twice as many projections. \end{itemdescr} \rSec3[is.heap]{\tcode{is_heap}} @@ -5177,10 +7896,10 @@ \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last) == last}. +\effects +Equivalent to: \tcode{return is_heap_until(first, last) == last;} \end{itemdescr} - \indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} template @@ -5190,7 +7909,11 @@ \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(std::forward(exec), first, last) == last}. +\effects +Equivalent to: +\begin{codeblock} +return is_heap_until(std::forward(exec), first, last) == last; +\end{codeblock} \end{itemdescr} @@ -5203,10 +7926,10 @@ \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last, comp) == last}. +\effects +Equivalent to: \tcode{return is_heap_until(first, last, comp) == last;} \end{itemdescr} - \indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} template @@ -5217,12 +7940,30 @@ \begin{itemdescr} \pnum -\returns +\effects +Equivalent to: \begin{codeblock} -is_heap_until(std::forward(exec), first, last, comp) == last +return is_heap_until(std::forward(exec), first, last, comp) == last; \end{codeblock} \end{itemdescr} +\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 = {}); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return ranges::is_heap_until(first, last, comp, proj) == last;} +\end{itemdescr} \indexlibrary{\idxcode{is_heap_until}}% \begin{itemdecl} @@ -5243,15 +7984,28 @@ is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); -\end{itemdecl} +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 = {}); +} +\end{itemdecl} \begin{itemdescr} \pnum -\returns If \tcode{(last - first) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is a heap. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\returns +The last iterator \tcode{i} in \crange{first}{last} for which the +range \range{first}{i} is a heap with respect to \tcode{comp} and \tcode{proj}. \pnum \complexity Linear. @@ -5265,6 +8019,12 @@ template constexpr const T& min(const T& a, const T& b); 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 = {}); +} \end{itemdecl} \begin{itemdescr} @@ -5280,34 +8040,55 @@ \pnum \remarks Returns the first argument when the arguments are equivalent. +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum \complexity -Exactly one comparison. +Exactly one comparison and two applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{min}}% \begin{itemdecl} template - constexpr T min(initializer_list t); + constexpr T min(initializer_list r); template - constexpr T min(initializer_list t, Compare comp); + 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +\requires +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} shall be \oldconcept{Copy\-Constructible}. For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. \pnum -\returns The smallest value in the initializer list. +\returns The smallest value in the input range. \pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the smallest. +\remarks Returns a copy of the leftmost element when several elements are equivalent to the smallest. +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum \complexity -Exactly \tcode{t.size() - 1} comparisons. +Exactly \tcode{ranges::distance(r) - 1} comparisons +and twice as many applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{max}}% @@ -5315,6 +8096,12 @@ template constexpr const T& max(const T& a, const T& b); 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 = {}); +} \end{itemdecl} \begin{itemdescr} @@ -5330,34 +8117,55 @@ \pnum \remarks Returns the first argument when the arguments are equivalent. +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum \complexity -Exactly one comparison. +Exactly one comparison and two applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{max}}% \begin{itemdecl} template - constexpr T max(initializer_list t); + constexpr T max(initializer_list r); template - constexpr T max(initializer_list t, Compare comp); + 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +\requires +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} shall be \oldconcept{Copy\-Constructible}. For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. \pnum -\returns The largest value in the initializer list. +\returns The largest value in the input range. \pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the largest. +\remarks Returns a copy of the leftmost element when several elements are equivalent to the largest. +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum \complexity -Exactly \tcode{t.size() - 1} comparisons. +Exactly \tcode{ranges::distance(r) - 1} comparisons +and twice as many applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{minmax}}% @@ -5365,6 +8173,13 @@ template constexpr pair minmax(const T& a, const T& b); 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 = {}); +} \end{itemdecl} @@ -5376,17 +8191,18 @@ \pnum \returns -\tcode{pair(b, a)} if \tcode{b} is smaller -than \tcode{a}, and -\tcode{pair(a, b)} otherwise. +\tcode{\{(b, a)\}} if \tcode{b} is smaller than \tcode{a}, and +\tcode{\{a, b\}} otherwise. \pnum \remarks -Returns \tcode{pair(a, b)} when the arguments are equivalent. +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum \complexity -Exactly one comparison. +Exactly one comparison and two applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{minmax}}% @@ -5395,24 +8211,45 @@ constexpr pair minmax(initializer_list t); 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +\requires +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} shall be \oldconcept{Copy\-Constructible}. For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. \pnum -\returns \tcode{pair(x, y)}, where \tcode{x} has the smallest and \tcode{y} has the -largest value in the initializer list. +\returns +Let \tcode{X} be the return type. Returns +\tcode{X{x, y}}, where \tcode{x} is a copy of the leftmost element with +the smallest and \tcode{y} a copy of the rightmost element with the +largest value in the input range. \pnum -\remarks \tcode{x} is a copy of the leftmost argument when several arguments are equivalent to -the smallest. \tcode{y} is a copy of the rightmost argument when several arguments are -equivalent to the largest. +\remarks +An invocation may explicitly specify an argument +for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \pnum -\complexity At most $(3/2)\tcode{t.size()}$ applications of the corresponding predicate. +\complexity +At most $(3/2)\tcode{ranges::distance(r)}$ applications of the corresponding predicate +and twice as many applications of the projection, if any. \end{itemdescr} \indexlibrary{\idxcode{min_element}}% @@ -5431,9 +8268,24 @@ ForwardIterator min_element(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \returns The first iterator @@ -5443,11 +8295,11 @@ such that for every iterator \tcode{j} in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. +\range{first}{last}, +\begin{codeblock} +bool(invoke(comp, invoke(proj, *j), invoke(proj, *i))) +\end{codeblock} +is \tcode{false}. Returns \tcode{last} if @@ -5457,7 +8309,7 @@ \complexity Exactly $\max(\tcode{last - first - 1}, 0)$ -applications of the corresponding comparisons. +comparisons and twice as many projections. \end{itemdescr} \indexlibrary{\idxcode{max_element}}% @@ -5475,9 +8327,24 @@ ForwardIterator max_element(ExecutionPolicy&& exec, 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + \pnum \returns The first iterator @@ -5487,11 +8354,11 @@ such that for every iterator \tcode{j} in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*i < *j)} -or -\tcode{comp(*i, *j) == false}. +\range{first}{last}, +\begin{codeblock} +bool(invoke(comp, invoke(proj, *i), invoke(proj, *j))) +\end{codeblock} +is \tcode{false}. Returns \tcode{last} if @@ -5501,7 +8368,7 @@ \complexity Exactly $\max(\tcode{last - first - 1}, 0)$ -applications of the corresponding comparisons. +comparisons and twice as many projections. \end{itemdescr} \indexlibrary{\idxcode{minmax_element}}% @@ -5521,14 +8388,25 @@ pair 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{make_pair(first, first)} if \range{first}{last} is empty, otherwise -\tcode{make_pair(m, M)}, where \tcode{m} is +\tcode{\{first, first\}} if \range{first}{last} is empty, otherwise +\tcode{\{m, M\}}, where \tcode{m} is the first iterator in \range{first}{last} such that no iterator in the range refers to a smaller element, and where \tcode{M} is the last iterator\footnote{This behavior intentionally differs from \tcode{max_element()}.} @@ -5536,9 +8414,10 @@ \pnum \complexity +Let $N$ be \tcode{last - first}. At most $\max(\bigl\lfloor{\frac{3}{2}} (N-1)\bigr\rfloor, 0)$ -applications of the corresponding predicate, where $N$ is \tcode{last - first}. +comparisons and twice as many applications of the projection, if any. \end{itemdescr} \rSec2[alg.clamp]{Bounded value} @@ -5600,31 +8479,46 @@ ForwardIterator1 first1, ForwardIterator1 last1, 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 = {}); +} \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} -if the sequence of elements defined by the range +if and only if the sequence of elements defined by the range \range{first1}{last1} is lexicographically less than the sequence of elements defined by the range -\range{first2}{last2} and -\tcode{false} -otherwise. +\range{first2}{last2}. \pnum \complexity At most $2 \min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ -applications of the corresponding comparison. +applications of the corresponding comparison and each projection, if any. \pnum \remarks If two sequences have the same number of elements and their corresponding elements (if any) are equivalent, then neither sequence is lexicographically less than the other. -If one sequence is a prefix of the other, then the shorter sequence is +If one sequence is a proper prefix of the other, then the shorter sequence is lexicographically less than the longer sequence. Otherwise, the lexicographical comparison of the sequences yields the same result as the comparison of the first corresponding pair of @@ -5632,11 +8526,12 @@ \pnum \begin{example} -The following sample implementation satisfies these requirements: +\tcode{ranges::lexicographical_compare(I1, S1, I2, S2, Comp, Proj1, Proj2)} +could be implemented as: \begin{codeblock} for ( ; first1 != last1 && first2 != last2 ; ++first1, (void) ++first2) { - if (*first1 < *first2) return true; - if (*first2 < *first1) return false; + if (invoke(comp, invoke(proj1, *first1), invoke(proj2, *first2))) return true; + if (invoke(comp, invoke(proj2, *first2), invoke(proj1, *first1))) return false; } return first1 == last1 && first2 != last2; \end{codeblock} @@ -5746,13 +8641,32 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. \pnum \effects @@ -5760,17 +8674,14 @@ \range{first}{last} and transforms it into the next permutation. The next permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. +lexicographically sorted with respect to \tcode{comp} and \tcode{proj}. +If no such permutation exists, +transforms the sequence into the first permutation; +that is, the ascendingly-sorted one. \pnum \returns -\tcode{true} -if such a permutation exists. -Otherwise, it transforms the sequence into the smallest permutation, -that is, the ascendingly sorted one, and returns -\tcode{false}. +\tcode{true} if and only if a next permutation was found. \pnum \complexity @@ -5788,13 +8699,32 @@ template 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 = {}); +} \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} shall meet the +\oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. \pnum \effects @@ -5802,17 +8732,14 @@ \range{first}{last} and transforms it into the previous permutation. The previous permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. +lexicographically sorted with respect to \tcode{comp} and \tcode{proj}. +If no such permutation exists, +transforms the sequence into the last permutation; +that is, the descendingly-sorted one. \pnum \returns -\tcode{true} -if such a permutation exists. -Otherwise, it transforms the sequence into the largest permutation, -that is, the descendingly sorted one, and returns -\tcode{false}. +\tcode{true} if and only if a previous permutation was found. \pnum \complexity @@ -6058,6 +8985,28 @@ throughout this subclause is intentional. \end{note} +\rSec2[numerics.defns]{Definitions} + +\indexlibrary{generalized_noncommutative_sum@\tcode{\placeholder{GENERALIZED_NONCOMMUTATIVE_SUM}}}% +\pnum +Define \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aN)} as follows: +\begin{itemize} +\item +\tcode{a1} when \tcode{N} is \tcode{1}, otherwise + +\item +\tcode{op(\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aK),} \\ +\tcode{\phantom{op(}\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, ..., aN))} +for any \tcode{K} where $1 < \mathtt{K}+1 = \mathtt{M} \leq \mathtt{N}$. +\end{itemize} + +\indexlibrary{generalized_sum@\tcode{\placeholder{GENERALIZED_SUM}}}% +\pnum +Define \tcode{\placeholdernc{GENERALIZED_SUM}(op, a1, ..., aN)} as +\tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, ..., bN)}, +where +\tcode{b1, ..., bN} may be any permutation of \tcode{a1, ..., aN}. + \rSec2[accumulate]{Accumulate} \indexlibrary{\idxcode{accumulate}}% diff --git a/source/atomics.tex b/source/atomics.tex index 8474ede06f..ff4339ec92 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -43,6 +43,7 @@ // \ref{atomics.lockfree}, lock-free property #define ATOMIC_BOOL_LOCK_FREE @\unspec@ #define ATOMIC_CHAR_LOCK_FREE @\unspec@ + #define ATOMIC_CHAR8_T_LOCK_FREE @\unspec@ #define ATOMIC_CHAR16_T_LOCK_FREE @\unspec@ #define ATOMIC_CHAR32_T_LOCK_FREE @\unspec@ #define ATOMIC_WCHAR_T_LOCK_FREE @\unspec@ @@ -203,6 +204,7 @@ using atomic_ulong = atomic; using atomic_llong = atomic; using atomic_ullong = atomic; + using atomic_char8_t = atomic; using atomic_char16_t = atomic; using atomic_char32_t = atomic; using atomic_wchar_t = atomic; @@ -272,6 +274,7 @@ \indexlibrary{\idxcode{atomic_ulong}}% \indexlibrary{\idxcode{atomic_llong}}% \indexlibrary{\idxcode{atomic_ullong}}% +\indexlibrary{\idxcode{atomic_char8_t}}% \indexlibrary{\idxcode{atomic_char16_t}}% \indexlibrary{\idxcode{atomic_char32_t}}% \indexlibrary{\idxcode{atomic_wchar_t}}% @@ -379,75 +382,90 @@ release sequence headed by \placeholder{A}. \pnum -There shall be a single total order \placeholder{S} on all \tcode{memory_order::seq_cst} -operations, consistent with the ``happens before'' order and modification orders for all -affected locations, such that each \tcode{memory_order::seq_cst} operation -\placeholder{B} that loads a -value from an atomic object \placeholder{M} -observes one of the following values: - +An atomic operation \placeholder{A} on some atomic object \placeholder{M} is +\defn{coherence-ordered before} +another atomic operation \placeholder{B} on \placeholder{M} if \begin{itemize} -\item the result of the last modification \placeholder{A} of \placeholder{M} that precedes -\placeholder{B} in \placeholder{S}, if it exists, or - -\item if \placeholder{A} exists, the result of some modification of \placeholder{M} -that is not -\tcode{memory_order::seq_cst} and that does not happen before \placeholder{A}, or - -\item if \placeholder{A} does not exist, the result of some modification of \placeholder{M} -that is not -\tcode{memory_order::seq_cst}. +\item \placeholder{A} is a modification, and +\placeholder{B} reads the value stored by \placeholder{A}, or +\item \placeholder{A} precedes \placeholder{B} +in the modification order of \placeholder{M}, or +\item \placeholder{A} and \placeholder{B} are not +the same atomic read-modify-write operation, and +there exists an atomic modification \placeholder{X} of \placeholder{M} +such that \placeholder{A} reads the value stored by \placeholder{X} and +\placeholder{X} precedes \placeholder{B} +in the modification order of \placeholder{M}, or +\item there exists an atomic modification \placeholder{X} of \placeholder{M} +such that \placeholder{A} is coherence-ordered before \placeholder{X} and +\placeholder{X} is coherence-ordered before \placeholder{B}. \end{itemize} -\begin{note} Although it is not explicitly required that \placeholder{S} include locks, it can -always be extended to an order that does include lock and unlock operations, since the -ordering between those is already included in the ``happens before'' ordering. \end{note} - \pnum -For an atomic operation \placeholder{B} that reads the value of an atomic object \placeholder{M}, -if there is a \tcode{memory_order::seq_cst} fence \placeholder{X} sequenced before \placeholder{B}, -then \placeholder{B} observes either the last \tcode{memory_order::seq_cst} modification of -\placeholder{M} preceding \placeholder{X} in the total order \placeholder{S} or a later modification of -\placeholder{M} in its modification order. - -\pnum -For atomic operations \placeholder{A} and \placeholder{B} on an atomic object \placeholder{M}, where -\placeholder{A} modifies \placeholder{M} and \placeholder{B} takes its value, if there is a -\tcode{memory_order::seq_cst} fence \placeholder{X} such that \placeholder{A} is sequenced before -\placeholder{X} and \placeholder{B} follows \placeholder{X} in \placeholder{S}, then \placeholder{B} observes -either the effects of \placeholder{A} or a later modification of \placeholder{M} in its -modification order. +There is a single total order \placeholder{S} +on all \tcode{memory_order::seq_cst} operations, including fences, +that satisfies the following constraints. +First, if \placeholder{A} and \placeholder{B} are +\tcode{memory_order::seq_cst} operations and +\placeholder{A} strongly happens before \placeholder{B}, +then \placeholder{A} precedes \placeholder{B} in \placeholder{S}. +Second, for every pair of atomic operations \placeholder{A} and +\placeholder{B} on an object \placeholder{M}, +where \placeholder{A} is coherence-ordered before \placeholder{B}, +the following four conditions are required to be satisfied by \placeholder{S}: +\begin{itemize} +\item if \placeholder{A} and \placeholder{B} are both +\tcode{memory_order::seq_cst} operations, +then \placeholder{A} precedes \placeholder{B} in \placeholder{S}; and +\item if \placeholder{A} is a \tcode{memory_order::seq_cst} operation and +\placeholder{B} happens before +a \tcode{memory_order::seq_cst} fence \placeholder{Y}, +then \placeholder{A} precedes \placeholder{Y} in \placeholder{S}; and +\item if a \tcode{memory_order::seq_cst} fence \placeholder{X} +happens before \placeholder{A} and +\placeholder{B} is a \tcode{memory_order::seq_cst} operation, +then \placeholder{X} precedes \placeholder{B} in \placeholder{S}; and +\item if a \tcode{memory_order::seq_cst} fence \placeholder{X} +happens before \placeholder{A} and +\placeholder{B} happens before +a \tcode{memory_order::seq_cst} fence \placeholder{Y}, +then \placeholder{X} precedes \placeholder{Y} in \placeholder{S}. +\end{itemize} \pnum -For atomic operations \placeholder{A} and \placeholder{B} on an atomic object \placeholder{M}, where -\placeholder{A} modifies \placeholder{M} and \placeholder{B} takes its value, if there are -\tcode{memory_order::seq_cst} fences \placeholder{X} and \placeholder{Y} such that \placeholder{A} is -sequenced before \placeholder{X}, \placeholder{Y} is sequenced before \placeholder{B}, and \placeholder{X} -precedes \placeholder{Y} in \placeholder{S}, then \placeholder{B} observes either the effects of -\placeholder{A} or a later modification of \placeholder{M} in its modification order. +\begin{note} +This definition ensures that \placeholder{S} is consistent with +the modification order of any atomic object \placeholder{M}. +It also ensures that +a \tcode{memory_order::seq_cst} load \placeholder{A} of \placeholder{M} +gets its value either from the last modification of \placeholder{M} +that precedes \placeholder{A} in \placeholder{S} or +from some non-\tcode{memory_order::seq_cst} modification of \placeholder{M} +that does not happen before any modification of \placeholder{M} +that precedes \placeholder{A} in \placeholder{S}. +\end{note} \pnum -For atomic modifications \placeholder{A} and \placeholder{B} of an atomic object \placeholder{M}, -\placeholder{B} occurs later than \placeholder{A} in the modification order of \placeholder{M} if: - -\begin{itemize} -\item there is a \tcode{memory_order::seq_cst} fence \placeholder{X} such that \placeholder{A} -is sequenced before \placeholder{X}, and \placeholder{X} precedes \placeholder{B} in \placeholder{S}, or -\item there is a \tcode{memory_order::seq_cst} fence \placeholder{Y} such that \placeholder{Y} -is sequenced before \placeholder{B}, and \placeholder{A} precedes \placeholder{Y} in \placeholder{S}, or -\item there are \tcode{memory_order::seq_cst} fences \placeholder{X} and \placeholder{Y} such that \placeholder{A} -is sequenced before \placeholder{X}, \placeholder{Y} is sequenced before \placeholder{B}, -and \placeholder{X} precedes \placeholder{Y} in \placeholder{S}. -\end{itemize} - +\begin{note} +We do not require that \placeholder{S} be consistent with +``happens before''\iref{intro.races}. +This allows more efficient implementation +of \tcode{memory_order::acquire} and \tcode{memory_order::release} +on some machine architectures. +It can produce surprising results +when these are mixed with \tcode{memory_order::seq_cst} accesses. +\end{note} \pnum -\begin{note} \tcode{memory_order::seq_cst} ensures sequential consistency only for a -program that is free of data races and uses exclusively \tcode{memory_order::seq_cst} -operations. Any use of weaker ordering will invalidate this guarantee unless extreme -care is used. In particular, \tcode{memory_order::seq_cst} fences ensure a total order -only for the fences themselves. Fences cannot, in general, be used to restore sequential -consistency for atomic operations with weaker ordering specifications. \end{note} +\begin{note} +\tcode{memory_order::seq_cst} ensures sequential consistency only +for a program that is free of data races and +uses exclusively \tcode{memory_order::seq_cst} atomic operations. +Any use of weaker ordering will invalidate this guarantee +unless extreme care is used. +In many cases, \tcode{memory_order::seq_cst} atomic operations are reorderable +with respect to other atomic operations performed by the same thread. +\end{note} \pnum Implementations should ensure that no ``out-of-thin-air'' values are computed that @@ -520,6 +538,7 @@ \indexlibrary{\idxcode{ATOMIC_BOOL_LOCK_FREE}}% \indexlibrary{\idxcode{ATOMIC_CHAR_LOCK_FREE}}% +\indexlibrary{\idxcode{ATOMIC_CHAR8_T_LOCK_FREE}}% \indexlibrary{\idxcode{ATOMIC_CHAR16_T_LOCK_FREE}}% \indexlibrary{\idxcode{ATOMIC_CHAR32_T_LOCK_FREE}}% \indexlibrary{\idxcode{ATOMIC_WCHAR_T_LOCK_FREE}}% @@ -532,6 +551,7 @@ \begin{codeblock} #define ATOMIC_BOOL_LOCK_FREE @\unspec@ #define ATOMIC_CHAR_LOCK_FREE @\unspec@ +#define ATOMIC_CHAR8_T_LOCK_FREE @\unspec@ #define ATOMIC_CHAR16_T_LOCK_FREE @\unspec@ #define ATOMIC_CHAR32_T_LOCK_FREE @\unspec@ #define ATOMIC_WCHAR_T_LOCK_FREE @\unspec@ @@ -582,7 +602,6 @@ static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; - atomic_ref() = delete; atomic_ref& operator=(const atomic_ref&) = delete; explicit atomic_ref(T&); @@ -848,7 +867,8 @@ \pnum \effects Retrieves the value in \tcode{expected}. -It then atomically compares the value referenced by \tcode{*ptr} for equality +It then atomically compares the value representation of +the value referenced by \tcode{*ptr} for equality with that previously retrieved from \tcode{expected}, and if \tcode{true}, replaces the value referenced by \tcode{*ptr} with that in \tcode{desired}. @@ -865,7 +885,7 @@ the value \tcode{memory_order_relaxed}. If and only if the comparison is \tcode{false} then, after the atomic operation, -the contents of the memory in \tcode{expected} are replaced by +the value in \tcode{expected} is replaced by the value read from the value referenced by \tcode{*ptr} during the atomic comparison. If the operation returns \tcode{true}, @@ -912,6 +932,7 @@ \tcode{unsigned long}, \tcode{long long}, \tcode{unsigned long long}, +\tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, \tcode{wchar_t}, @@ -934,7 +955,6 @@ static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; - atomic_ref() = delete; atomic_ref& operator=(const atomic_ref&) = delete; explicit atomic_ref(@\placeholder{integral}@&); @@ -1014,8 +1034,13 @@ \pnum \indextext{signed integer representation!two's complement}% \remarks For signed integer types, -arithmetic is defined to use two's complement representation. -There are no undefined results. +the result is as if the object value and parameters +were converted to their corresponding unsigned types, +the computation performed on those types, and +the result converted back to the signed type. +\begin{note} +There are no undefined results arising from the computation. +\end{note} \end{itemdescr} \indexlibrarymember{operator+=}{atomic_ref<\placeholder{integral}>}% @@ -1057,7 +1082,6 @@ static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; - atomic_ref() = delete; atomic_ref& operator=(const atomic_ref&) = delete; explicit atomic_ref(@\placeholder{floating-point}@&); @@ -1156,7 +1180,6 @@ static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; - atomic_ref() = delete; atomic_ref& operator=(const atomic_ref&) = delete; explicit atomic_ref(T*&); @@ -1335,9 +1358,11 @@ The specialization \tcode{atomic} is a standard-layout struct. \pnum -\begin{note} The representation of an atomic specialization need not have the same size as its -corresponding argument type. Specializations should have the same size whenever possible, as -this reduces the effort required to port existing code. \end{note} +\begin{note} +The representation of an atomic specialization +need not have the same size and alignment requirement as +its corresponding argument type. +\end{note} \rSec2[atomics.types.operations]{Operations on atomic types} @@ -1626,7 +1651,7 @@ \end{example} \begin{example} Because the expected value is updated only on failure, code releasing the memory containing the \tcode{expected} value on success will work. -E.g. list head insertion will act atomically and would not introduce a +For example, list head insertion will act atomically and would not introduce a data race in the following code: \begin{codeblock} do { @@ -1725,6 +1750,7 @@ \tcode{unsigned long}, \tcode{long long}, \tcode{unsigned long long}, +\tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, \tcode{wchar_t}, @@ -1879,8 +1905,15 @@ \pnum \indextext{signed integer representation!two's complement}% -\remarks For signed integer types, arithmetic is defined to use two's complement representation. -There are no undefined results. +\remarks For signed integer types, +the result is as if the object value and parameters +were converted to their corresponding unsigned types, +the computation performed on those types, and +the result converted back to the signed type. +\begin{note} +There are no undefined results arising from the computation. +\end{note} + \end{itemdescr} \indexlibrarymember{operator+=}{atomic}% diff --git a/source/basic.tex b/source/basic.tex index f80d293c18..b6ff96acde 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1776,19 +1776,13 @@ of that enumeration. \pnum -If a \grammarterm{pseudo-destructor-name}\iref{expr.pseudo} contains a -\grammarterm{nested-name-specifier}, the \grammarterm{type-name}{s} are looked -up as types in the scope designated by the -\grammarterm{nested-name-specifier}. Similarly, in a -\grammarterm{qualified-id} of the form: +In a \grammarterm{qualified-id} of the form: \begin{ncbnf} -\opt{nested-name-specifier} class-name \terminal{::} \terminal{\~} class-name +\opt{nested-name-specifier} type-name \terminal{::} \terminal{\~} type-name \end{ncbnf} - -the second \grammarterm{class-name} is looked up in the same scope as the -first. \begin{example} - +the second \grammarterm{type-name} is looked up in the same scope as the first. +\begin{example} \begin{codeblock} struct C { typedef int I; @@ -1808,8 +1802,10 @@ p->AB::~AB(); // explicitly calls the destructor for \tcode{A} } \end{codeblock} -\end{example} \begin{note} \ref{basic.lookup.classref} describes how name -lookup proceeds after the \tcode{.} and \tcode{->} operators. \end{note} +\end{example} +\begin{note} \ref{basic.lookup.classref} describes how name +lookup proceeds after the \tcode{.} and \tcode{->} operators. +\end{note} \rSec3[class.qual]{Class members} @@ -2222,9 +2218,6 @@ access\iref{expr.ref} is an \grammarterm{unqualified-id}, and the type of the object expression is of a class type \tcode{C}, the \grammarterm{unqualified-id} is looked up in the scope of class \tcode{C}. -For a pseudo-destructor call\iref{expr.pseudo}, -the \grammarterm{unqualified-id} is looked up in the context of the complete -\grammarterm{postfix-expression}. \pnum If the \grammarterm{unqualified-id} is \tcode{\~}\grammarterm{type-name}, the @@ -3329,7 +3322,7 @@ \indextext{\idxcode{new_handler}}% A program-supplied allocation function can obtain the address of the currently installed \tcode{new_handler} using the -\tcode{std::get_new_handler} function\iref{set.new.handler}. \end{note} +\tcode{std::get_new_handler} function\iref{get.new.handler}. \end{note} An allocation function that has a non-throwing exception specification\iref{except.spec} indicates failure by returning @@ -3582,7 +3575,7 @@ \tcode{alignof} expression\iref{expr.alignof}. Furthermore, the narrow character types\iref{basic.fundamental} shall have the weakest alignment requirement. -\begin{note} This enables the narrow character types to be used as the +\begin{note} This enables the ordinary character types to be used as the underlying type for an aligned memory area\iref{dcl.align}.\end{note} \pnum @@ -4027,16 +4020,14 @@ \indextext{object!byte copying and|)} \pnum -The \defn{object representation} -\indextext{representation!object}% +The \defnx{object representation}{representation!object} of an object of type \tcode{T} is the sequence of \placeholder{N} \tcode{unsigned char} objects taken up by the object of type \tcode{T}, where \placeholder{N} equals -\tcode{sizeof(T)}. The -\indextext{representation!value}% -\defn{value representation} -of an object is the set of bits that hold -the value of type \tcode{T}. +\tcode{sizeof(T)}. +The \defnx{value representation}{representation!value} +of an object of type \tcode{T} is the set of bits +that participate in representing a value of type \tcode{T}. Bits in the object representation that are not part of the value representation are \defn{padding bits}. For trivially copyable types, the value representation is @@ -4174,51 +4165,7 @@ \rSec2[basic.fundamental]{Fundamental types} \pnum -\indextext{type!integral}% -\indextext{floating-point type|see{type, floating-point}}% \indextext{type!implementation-defined \tcode{sizeof}}% -\indextext{type!Boolean}% -\indextext{type!\idxcode{char}}% -\indextext{type!character}% -Objects declared as characters (\tcode{char}) shall be large enough to -store any member of the implementation's basic character set. If a -character from this set is stored in a character object, the integral -value of that character object is equal to the value of the single -character literal form of that character. It is \impldef{signedness of \tcode{char}} -whether a \tcode{char} object can hold negative values. -\indextext{\idxcode{char}!implementation-defined sign of}% -\indextext{type!\idxcode{signed char}}% -\indextext{type!\idxcode{unsigned char}}% -Characters can be explicitly declared \tcode{unsigned} or -\tcode{signed}. -\indextext{character!\idxcode{signed}}% -Plain \tcode{char}, \tcode{signed char}, and \tcode{unsigned char} are -three distinct types, collectively called -\defnx{narrow character types}{type!narrow character}. -A \tcode{char}, a \tcode{signed char}, and an -\tcode{unsigned char} occupy the same amount of storage and have the -same alignment requirements\iref{basic.align}; that is, they have the -same object representation. For narrow character types, all bits of the object -representation participate in the value representation. -\begin{note} -A bit-field of narrow character type whose length is larger than -the number of bits in the object representation of that type has -padding bits; see~\ref{basic.types}. -\end{note} -For unsigned narrow -character types, each possible bit pattern of the value representation -represents a distinct number. These requirements do not hold for other types. In -any particular implementation, a plain \tcode{char} object can take on -either the same values as a \tcode{signed char} or an \tcode{unsigned -char}; which one is \impldef{representation of \tcode{char}}. -For each value \placeholder{i} of type \tcode{unsigned char} in the range -0 to 255 inclusive, there exists a value \placeholder{j} of type -\tcode{char} such that the result of an integral -conversion\iref{conv.integral} from \placeholder{i} to \tcode{char} is -\placeholder{j}, and the result of an integral conversion from -\placeholder{j} to \tcode{unsigned char} is \placeholder{i}. - -\pnum \indextext{type!standard signed integer}% There are five \defnx{standard signed integer types}{standard signed integer type} : \indextext{type!\idxcode{signed char}}% @@ -4234,20 +4181,21 @@ \indextext{type!signed integer}% There may also be \impldef{extended signed integer types} \defnx{extended signed integer types}{extended signed integer type}. -The standard and -extended signed integer types are collectively called +The standard and extended signed integer types are collectively called \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. \indextext{integral type!implementation-defined \tcode{sizeof}}% \begin{note} -Plain \tcode{int}s -are intended to have -the natural size suggested by the architecture of the -execution environment; +Plain \tcode{int}s are intended to have +the natural size suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs. \end{note} \pnum \indextext{type!\idxcode{unsigned}}% +\indextext{type!unsigned integer}% For each of the standard signed integer types, there exists a corresponding (but different) \indextext{type!standard unsigned integer}% @@ -4259,24 +4207,79 @@ \indextext{type!\idxcode{unsigned long long}}% ``\tcode{unsigned char}'', ``\tcode{unsigned short int}'', ``\tcode{unsigned int}'', ``\tcode{unsigned long int}'', and -``\tcode{unsigned long long int}'', each of -which occupies the same amount of storage and has the same alignment -requirements\iref{basic.align} as the corresponding signed integer -type\footnote{See~\ref{dcl.type.simple} regarding the correspondence between types and -the sequences of \grammarterm{type-specifier}{s} that designate them.}; -that is, each signed integer type has the same object representation as -its corresponding unsigned integer type. +``\tcode{unsigned long long int}''. \indextext{type!extended unsigned integer}% -\indextext{type!unsigned integer}% -Likewise, for each of the extended signed integer types there exists a -corresponding -\defn{extended unsigned integer type} with the same amount of storage and alignment -requirements. The standard and extended unsigned integer types are -collectively called \defnx{unsigned integer types}{unsigned integer type}. The range of non-negative -values of a signed integer type is -a subrange of the corresponding unsigned integer type, -the representation of the same value in each of the two types is the same, and -the value representation of each corresponding signed/unsigned type shall be the same. +Likewise, for each of the extended signed integer types, +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} +as the corresponding signed integer type. +\indextext{arithmetic!\idxcode{unsigned}}% +The range of representable values for the unsigned type is +$0$ to $2^N-1$ (inclusive); +arithmetic for the unsigned type is performed modulo $2^N$. +\begin{note} +Unsigned arithmetic does not overflow. +Overflow for signed arithmetic yields undefined behavior\iref{expr.pre}. +\end{note} + +\pnum +\indextext{signed integer representation!two's complement}% +An unsigned integer type has the same +object representation, +value representation, and +alignment requirements\iref{basic.align} +as the corresponding signed integer type. +For each value $x$ of a signed integer type, +the value of the corresponding unsigned integer type +congruent to $x$ modulo $2^N$ has the same value +of corresponding bits in its value representation.\footnote{This +is also known as two's complement representation.} +\begin{example} +The value $-1$ of a signed integer type has the same representation as +the largest value of the corresponding unsigned type. +\end{example} + +\begin{floattable}{Minimum range exponent}{tab:range.exponent}{ll} +\topline +\lhdr{Type} & \rhdr{Minimum range exponent $N$} \\ +\capsep +\tcode{signed char} & 8 \\ +\tcode{short} & 16 \\ +\tcode{int} & 16 \\ +\tcode{long} & 32 \\ +\tcode{long long} & 64 \\ +\end{floattable} + +\pnum +The range exponent of each signed integer type +shall not be less than the values specified in \tref{range.exponent}. +The value representation of a signed or unsigned integer type +comprises $N$ bits, where N is the respective range exponent. +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. +\begin{note} +Padding bits have unspecified value, but do not cause traps. +See also ISO C 6.2.6.2. +\end{note} +\begin{note} +The signed and unsigned integer types satisfy +the constraints given in ISO C 5.2.4.2.1. +\end{note} +Except as specified above, +the range exponent of a signed or unsigned integer type is +\impldef{range exponent of integral type}. + +\pnum +Each value $x$ of an unsigned integer type with range exponent $N$ has +a unique representation $x = x_0 2^0 + x_1 2^1 + \ldots + x_{N-1} 2^{N-1}$, +where each coefficient $x_i$ is either 0 or 1; +this is called the \defn{base-2 representation} of $x$. +The base-2 representation of a value of signed integer type is +the base-2 representation of the congruent value +of the corresponding unsigned integer type. \indextext{type!standard integer}% \indextext{type!extended integer}% The standard signed integer types and standard unsigned integer types @@ -4284,73 +4287,107 @@ signed integer types and extended unsigned integer types are collectively called the \defnx{extended integer types}{extended integer type}. -The signed and unsigned integer types shall satisfy -the constraints given in the C standard, subclause 5.2.4.2.1. \pnum -\indextext{arithmetic!\idxcode{unsigned}}% -Unsigned integers shall obey the laws of arithmetic modulo $2^n$ where $n$ is -the number of bits in the value representation of that particular size of -integer.\footnote{This implies that -unsigned arithmetic does not overflow because a result -that cannot be represented by the resulting unsigned integer type is -reduced modulo the number that is one greater than the largest value -that can be represented by the resulting unsigned integer type.} +\indextext{underlying type|see{type, underlying}}% +A fundamental type specified to have +a signed or unsigned integer type as its \defn{underlying type} has +the same object representation, +value representation, +alignment requirements\iref{basic.align}, and +range of representable values as the underlying type. +Further, each value has the same representation in both types. \pnum +\indextext{type!\idxcode{char}}% +\indextext{type!character}% +\indextext{type!ordinary character}% +\indextext{type!narrow character}% +\indextext{\idxcode{char}!implementation-defined sign of}% +\indextext{type!\idxcode{signed char}}% +\indextext{character!\idxcode{signed}}% +\indextext{type!\idxcode{unsigned char}}% +Type \tcode{char} is a distinct type +that has an \impldef{underlying type of \tcode{char}} choice of +``\tcode{signed char}'' or ``\tcode{unsigned char}'' as its underlying type. +The values of type \tcode{char} can represent distinct codes +for all members of the implementation's basic character set. +The three types \tcode{char}, \tcode{signed char}, and \tcode{unsigned char} +are collectively called +\defnx{ordinary character types}{type!ordinary character}. +The ordinary character types and \tcode{char8_t} +are collectively called \defnx{narrow character types}{narrow character type}. +For narrow character types, +each possible bit pattern of the object representation represents +a distinct value. +\begin{note} +This requirement does not hold for other types. +\end{note} +\begin{note} +A bit-field of narrow character type whose width is larger than +the range exponent of that type has padding bits; see \ref{basic.types}. +\end{note} + +\pnum +\indextext{\idxcode{wchar_t}|see{type, \tcode{wchar_t}}}% +\indextext{type!\idxcode{wchar_t}}% +\indextext{type!underlying!\idxcode{wchar_t}}% +Type \tcode{wchar_t} is a distinct type that has +an \impldef{underlying type of \tcode{wchar_t}} +signed or unsigned integer type as its underlying type. +The values of type \tcode{wchar_t} can represent +distinct codes for all members of the largest extended character set +specified among the supported locales\iref{locale}. + +\pnum +\indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% +\indextext{type!\idxcode{char8_t}}% +\indextext{type!underlying!\idxcode{char8_t}}% +Type \tcode{char8_t} denotes a distinct type +whose underlying type is \tcode{unsigned char}. \indextext{\idxcode{char16_t}|see{type, \tcode{char16_t}}}% \indextext{\idxcode{char32_t}|see{type, \tcode{char32_t}}}% -\indextext{\idxcode{wchar_t}|see{type, \tcode{wchar_t}}}% \indextext{type!\idxcode{char16_t}}% \indextext{type!\idxcode{char32_t}}% -\indextext{type!\idxcode{wchar_t}}% -\indextext{underlying type|see{type, underlying}}% \indextext{type!underlying!\idxcode{char16_t}}% \indextext{type!underlying!\idxcode{char32_t}}% -Type \tcode{wchar_t} is a distinct type whose values can represent -distinct codes for all members of the largest extended character set -specified among the supported locales\iref{locale}. Type -\tcode{wchar_t} shall have the same size, signedness, and alignment -requirements\iref{basic.align} as one of the other integral types, -called its \defnx{underlying type}{type!underlying!\idxcode{wchar_t}}. Types \tcode{char16_t} and -\tcode{char32_t} denote distinct types with the same size, signedness, -and alignment as \tcode{uint_least16_t} and \tcode{uint_least32_t}, -respectively, in \tcode{}, called the underlying types. +Types \tcode{char16_t} and \tcode{char32_t} denote distinct types +whose underlying types are \tcode{uint_least16_t} and \tcode{uint_least32_t}, +respectively, in \tcode{}. \pnum \indextext{Boolean type}% -Values of type \tcode{bool} are either \tcode{true} or -\tcode{false}.\footnote{Using a \tcode{bool} value in ways described by this document -as ``undefined'', such as by examining the value of an -uninitialized automatic object, might cause it to behave as if it is -neither \tcode{true} nor \tcode{false}.} -\begin{note} There are no \tcode{signed}, \tcode{unsigned}, \tcode{short}, -or \tcode{long bool} types or values. \end{note} Values of type -\tcode{bool} participate in integral promotions\iref{conv.prom}. - -\pnum -Types \tcode{bool}, \tcode{char}, \tcode{char16_t}, \tcode{char32_t}, -\tcode{wchar_t}, and the signed and unsigned integer types are +\indextext{type!Boolean}% +Type \tcode{bool} is a distinct type that has +the same object representation, +value representation, and +alignment requirements as +an \impldef{underlying type of \tcode{bool}} unsigned integer type. +The values of type \tcode{bool} are +\tcode{true} and \tcode{false}. +\begin{note} +There are no \tcode{signed}, \tcode{unsigned}, +\tcode{short}, or \tcode{long bool} types or values. +\end{note} + +\pnum +\indextext{type!integral}% +Types +\tcode{bool}, +\tcode{char}, \tcode{wchar_t}, +\tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, +and the signed and unsigned integer types are collectively called -\defnx{integral}{integral type} types.\footnote{Therefore, enumerations\iref{dcl.enum} are not integral; however, -enumerations can be promoted to integral types as specified -in~\ref{conv.prom}.} -A synonym for integral type is -\indextext{signed integer representation!ones' complement}% -\indextext{signed integer representation!two's complement}% -\indextext{signed integer representation!signed magnitude}% -\defn{integer type}. The representations of integral types shall -define values by use of a pure binary numeration system.\footnote{A positional -representation for integers that uses the binary digits 0 -and 1, in which the values represented by successive bits are additive, -begin with 1, and are multiplied by successive integral power of 2, -except perhaps for the bit with the highest position. (Adapted from the -\doccite{American National Dictionary for Information Processing Systems}.)} -\begin{example} This document permits two's complement, -ones' complement and signed magnitude representations for integral types. -\end{example} +\defnx{integral types}{integral type}. +A synonym for integral type is \defn{integer type}. +\begin{note} +Enumerations\iref{dcl.enum} are not integral; +however, unscoped enumerations can be promoted to integral types +as specified in \ref{conv.prom}. +\end{note} \pnum +\indextext{floating-point type|see{type, floating-point}}% There are three \defnx{floating-point types}{type!floating-point}: \indextext{type!\idxcode{float}}% \tcode{float}, @@ -4589,14 +4626,13 @@ \grammarterm{new-type-id}\iref{expr.new} when the object is created. \begin{itemize} \item A \defnadj{const}{object} is an object of type \tcode{const T} or a - non-mutable subobject of such an object. + non-mutable subobject of a const object. \item A \defnadj{volatile}{object} is an object of type - \tcode{volatile T}, a subobject of such an object, or a mutable - subobject of a const volatile object. + \tcode{volatile T} or a subobject of a volatile object. \item A \defnadj{const volatile}{object} is an object of type - \tcode{const volatile T}, a non-mutable subobject of such an object, + \tcode{const volatile T}, a non-mutable subobject of a const volatile object, a const subobject of a volatile object, or a non-mutable volatile subobject of a const object. \end{itemize} @@ -4711,7 +4747,7 @@ \indextext{type!\idxcode{wchar_t}}% \indextext{type!\idxcode{char16_t}}% \indextext{type!\idxcode{char32_t}}% -\item The ranks of \tcode{char16_t}, \tcode{char32_t}, and +\item The ranks of \tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, and \tcode{wchar_t} shall equal the ranks of their underlying types\iref{basic.fundamental}. @@ -4805,6 +4841,8 @@ \item a \grammarterm{constant-expression}\iref{expr.const}, \item +an immediate invocation\iref{expr.const}, +\item an \grammarterm{init-declarator}\iref{dcl.decl} or a \grammarterm{mem-initializer}\iref{class.base.init}, including the constituent expressions of the initializer, @@ -5071,17 +5109,13 @@ \end{note} \pnum -A \defn{release sequence} headed by a release operation \placeholder{A} on an atomic object -\placeholder{M} is a maximal contiguous sub-sequence of +A \defn{release sequence} headed +by a release operation \placeholder{A} on an atomic object \placeholder{M} +is a maximal contiguous sub-sequence of \indextext{side effects}% -side effects in the -modification order of \placeholder{M}, where the first operation is \tcode{A}, and -every subsequent operation - -\begin{itemize} -\item is performed by the same thread that performed \tcode{A}, or -\item is an atomic read-modify-write operation. -\end{itemize} +side effects in the modification order of \placeholder{M}, +where the first operation is \placeholder{A}, and +every subsequent operation is an atomic read-modify-write operation. \pnum Certain library calls \defn{synchronize with} other library calls performed by @@ -5106,8 +5140,8 @@ \placeholder{B} is an invocation of any specialization of \tcode{std::kill_dependency}\iref{atomics.order}, or \item -\placeholder{A} is the left operand of a built-in logical AND (\tcode{\&\&}, -see~\ref{expr.log.and}) or logical OR (\tcode{||}, see~\ref{expr.log.or}) +\placeholder{A} is the left operand of a built-in logical \logop{AND} (\tcode{\&\&}, +see~\ref{expr.log.and}) or logical \logop{OR} (\tcode{||}, see~\ref{expr.log.or}) operator, or \item \placeholder{A} is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) @@ -5195,17 +5229,39 @@ possible only through the use of consume operations. \end{note} \pnum -An evaluation \placeholder{A} \defn{strongly happens before} an evaluation \placeholder{B} +An evaluation \placeholder{A} \defn{simply happens before} an evaluation \placeholder{B} if either \begin{itemize} \item \placeholder{A} is sequenced before \placeholder{B}, or \item \placeholder{A} synchronizes with \placeholder{B}, or -\item \placeholder{A} strongly happens before \placeholder{X} and \placeholder{X} strongly happens before \placeholder{B}. +\item \placeholder{A} simply happens before \placeholder{X} and +\placeholder{X} simply happens before \placeholder{B}. \end{itemize} \begin{note} In the absence of consume operations, -the happens before and strongly happens before relations are identical. -Strongly happens before essentially excludes consume operations. +the happens before and simply happens before relations are identical. +\end{note} + +\pnum +An evaluation \placeholder{A} \defn{strongly happens before} +an evaluation \placeholder{D} if, either +\begin{itemize} +\item \placeholder{A} is sequenced before \placeholder{D}, or +\item \placeholder{A} synchronizes with \placeholder{D}, and +both \placeholder{A} and \placeholder{D} are +sequentially consistent atomic operations\iref{atomics.order}, or +\item there are evaluations \placeholder{B} and \placeholder{C} +such that \placeholder{A} is sequenced before \placeholder{B}, +\placeholder{B} simply happens before \placeholder{C}, and +\placeholder{C} is sequenced before \placeholder{D}, or +\item there is an evaluation \placeholder{B} such that +\placeholder{A} strongly happens before \placeholder{B}, and +\placeholder{B} strongly happens before \placeholder{D}. +\end{itemize} +\begin{note} +Informally, if \placeholder{A} strongly happens before \placeholder{B}, +then \placeholder{A} appears to be evaluated before \placeholder{B} +in all contexts. Strongly happens before excludes consume operations. \end{note} \pnum @@ -5669,15 +5725,9 @@ \pnum \indextext{initialization!static object@\tcode{static} object}% \indextext{initialization!constant}% -A \defn{constant initializer} for a variable or temporary object \tcode{o} -is an initializer whose full-expression is a -constant expression, except that if \tcode{o} is an object, -such an initializer may also invoke constexpr constructors -for \tcode{o} and its subobjects even if those objects are of non-literal class -types. \begin{note} Such a class may have a non-trivial destructor. \end{note} \defnx{Constant initialization}{constant initialization} is performed if a variable or temporary object with static or thread storage duration -is initialized by a constant initializer for the entity. +is initialized by a constant initializer\iref{expr.const} for the entity. \indextext{initialization!runtime}% If constant initialization is not performed, a variable with static storage duration\iref{basic.stc.static} or thread storage diff --git a/source/classes.tex b/source/classes.tex index 0e92764437..2502e797ad 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -422,12 +422,8 @@ \pnum \indextext{class name!\idxcode{typedef}}% -A \grammarterm{typedef-name}\iref{dcl.typedef} that names a class type, -or a cv-qualified version thereof, is also a \grammarterm{class-name}. If a -\grammarterm{typedef-name} that names a cv-qualified class type is used -where a \grammarterm{class-name} is required, the cv-qualifiers are -ignored. A \grammarterm{typedef-name} shall not be used as the -\grammarterm{identifier} in a \grammarterm{class-head}. +A \grammarterm{simple-template-id} is only a \grammarterm{class-name} +if its \grammarterm{template-name} names a class template. \rSec1[class.mem]{Class members}% \indextext{declaration!member}% @@ -448,6 +444,7 @@ template-declaration\br deduction-guide\br alias-declaration\br + opaque-enum-declaration\br empty-declaration \end{bnf} @@ -1125,10 +1122,12 @@ \indextext{\idxcode{const}!destructor and}% \indextext{\idxcode{volatile}!constructor and}% \indextext{\idxcode{volatile}!destructor and}% -Constructors\iref{class.ctor} and destructors\iref{class.dtor} shall -not be declared \tcode{const}, \tcode{volatile} or \tcode{const} -\tcode{volatile}. \begin{note} However, these functions can be invoked to -create and destroy objects with cv-qualified types, +\begin{note} +Constructors and destructors +cannot be declared \tcode{const}, \tcode{volatile}, or \tcode{const} +\tcode{volatile}. +However, these functions can be invoked +to create and destroy objects with cv-qualified types; see~\ref{class.ctor} and~\ref{class.dtor}. \end{note} @@ -1231,8 +1230,7 @@ constructor\iref{class.qual}. \end{itemize} -The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. In a constructor -declaration, each \grammarterm{decl-specifier} in the optional +In a constructor declaration, each \grammarterm{decl-specifier} in the optional \grammarterm{decl-specifier-seq} shall be \tcode{friend}, \tcode{inline}, \tcode{constexpr}, or an \grammarterm{explicit-specifier}. \begin{example} @@ -1775,11 +1773,11 @@ \indextext{operator!move assignment|see{assignment operator, move}}% A user-declared \term{copy} assignment operator \tcode{X::operator=} is a non-static non-template member function of class \tcode{X} with exactly one -parameter of type \tcode{X}, \tcode{X\&}, \tcode{const} \tcode{X\&}, -\tcode{volatile} \tcode{X\&} or \tcode{const} \tcode{volatile} -\tcode{X\&}.\footnote{Because a template assignment operator or an assignment -operator taking an rvalue reference parameter is never a copy assignment -operator, the presence of such an assignment operator does not suppress the +parameter of type \tcode{X}, \tcode{X\&}, \tcode{const X\&}, +\tcode{volatile X\&}, or \tcode{const volatile X\&}.\footnote{Because +a template assignment operator or an assignment operator +taking an rvalue reference parameter is never a copy assignment operator, +the presence of such an assignment operator does not suppress the implicit declaration of a copy assignment operator. Such assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and, if selected, will be used to assign an object.} @@ -1836,40 +1834,20 @@ \begin{itemize} \item -each direct base class -\tcode{B} -of -\tcode{X} +each direct base class \tcode{B} of \tcode{X} has a copy assignment operator whose parameter is of type -\tcode{const} -\tcode{B\&}, -\tcode{const} -\tcode{volatile} -\tcode{B\&} -or -\tcode{B}, -and +\tcode{const B\&}, \tcode{const volatile B\&}, or \tcode{B}, and \item -for all the non-static data members of -\tcode{X} -that are of a class type -\tcode{M} -(or array thereof), +for all the non-static data members of \tcode{X} +that are of a class type \tcode{M} (or array thereof), each such class type has a copy assignment operator whose parameter is of type -\tcode{const} -\tcode{M\&}, -\tcode{const} -\tcode{volatile} -\tcode{M\&} -or -\tcode{M}.\footnote{This implies that the reference parameter of the +\tcode{const M\&}, \tcode{const volatile M\&}, +or \tcode{M}.\footnote{This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a -\tcode{volatile} -lvalue; see~\ref{diff.class}.} +\tcode{volatile} lvalue; see~\ref{diff.class}.} \end{itemize} -Otherwise, the implicitly-declared copy -assignment operator +Otherwise, the implicitly-declared copy assignment operator will have the form \begin{codeblock} @@ -2137,8 +2115,7 @@ same class as the \grammarterm{nested-name-specifier}. \end{itemize} -The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. A -destructor shall take no arguments\iref{dcl.fct}. +A destructor shall take no arguments\iref{dcl.fct}. Each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} of a destructor declaration (if any) shall be \tcode{friend}, \tcode{inline}, or \tcode{virtual}. @@ -2408,7 +2385,7 @@ \begin{note} \indextext{fundamental type!destructor and}% The notation for explicit call of a destructor can be used for any scalar type -name\iref{expr.pseudo}. +name\iref{expr.prim.id.dtor}. Allowing this makes it possible to write code without having to know if a destructor exists for a given type. For example: @@ -2893,15 +2870,20 @@ \indextext{\idxcode{:}!bit-field declaration}% \indextext{declaration!bit-field}% -specifies a bit-field; -its length is set off from the bit-field name by a colon. The optional \grammarterm{attribute-specifier-seq} appertains to the entity being declared. The bit-field -attribute is not part of the type of the class member. The -\grammarterm{constant-expression} shall be an integral constant expression -with a value greater than or equal to zero. The -value of the integral constant expression may -be larger than the number of bits in the object -representation\iref{basic.types} of the bit-field's type; in such -cases the extra bits are padding bits\iref{basic.types}. +specifies a bit-field. +The optional \grammarterm{attribute-specifier-seq} appertains +to the entity being declared. +A bit-field shall not be a static member. +\indextext{bit-field!type of}% +A bit-field shall have integral or enumeration type; +the bit-field attribute is not part of the type of the class member. +The \grammarterm{constant-expression} shall be an integral constant expression +with a value greater than or equal to zero 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 +(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}% Allocation of bit-fields within a class object is \impldef{allocation of bit-fields within a class object}. @@ -2929,16 +2911,9 @@ \indextext{bit-field!alignment of}% As a special case, an unnamed bit-field with a width of zero specifies alignment of the next bit-field at an allocation unit boundary. Only -when declaring an unnamed bit-field may the value of the -\grammarterm{constant-expression} be equal to zero. +when declaring an unnamed bit-field may the width be zero. \pnum -\indextext{bit-field!type of}% -A bit-field shall not be a static member. A bit-field shall have -integral or enumeration type\iref{basic.fundamental}. -\indextext{Boolean}% -A \tcode{bool} value can successfully be stored in a bit-field of any -nonzero size. \indextext{bit-field!address of}% The address-of operator \tcode{\&} shall not be applied to a bit-field, so there are no pointers to bit-fields. @@ -2955,14 +2930,18 @@ \end{note} \pnum +If a value of integral type (other than \tcode{bool}) is stored +into a bit-field of width $N$ and the value would be representable +in a hypothetical signed or unsigned integer type +with range exponent $N$ and the same signedness as the bit-field's type, +the original value and the value of the bit-field compare equal. If the value \tcode{true} or \tcode{false} is stored into a bit-field of type \tcode{bool} of any size (including a one bit bit-field), the -original \tcode{bool} value and the value of the bit-field shall compare -equal. If the value of an enumerator is stored into a bit-field of the -same enumeration type and the number of bits in the bit-field is large +original \tcode{bool} value and the value of the bit-field compare +equal. If a value of an enumeration type is stored into a bit-field of the +same type and the width is large enough to hold all the values of that enumeration type\iref{dcl.enum}, -the original enumerator value and the value of the bit-field shall -compare equal. +the original value and the value of the bit-field compare equal. \begin{example} \begin{codeblock} @@ -3439,7 +3418,7 @@ \begin{bnf} \nontermdef{class-or-decltype}\br - \opt{nested-name-specifier} class-name\br + \opt{nested-name-specifier} type-name\br nested-name-specifier \terminal{template} simple-template-id\br decltype-specifier \end{bnf} @@ -3458,8 +3437,9 @@ \pnum \indextext{type!incomplete}% A \grammarterm{class-or-decltype} shall denote -a class type that is not -an incompletely defined class\iref{class}. +a (possibly cv-qualified) class type that is not +an incompletely defined class\iref{class.mem}; +any cv-qualifiers are ignored. The class denoted by the \grammarterm{class-or-decltype} of a \grammarterm{base-specifier} is called a \defnadj{direct}{base class} @@ -3467,8 +3447,8 @@ \indextext{base class}% \indextext{derivation|see{inheritance}}% During the lookup for a base class name, non-type names are -ignored\iref{basic.scope.hiding}. If the name found is not a -\grammarterm{class-name}, the program is ill-formed. A class \tcode{B} is a +ignored\iref{basic.scope.hiding}. +A class \tcode{B} is a base class of a class \tcode{D} if it is a direct base class of \tcode{D} or a direct base class of one of \tcode{D}'s base classes. A class is an \defnadj{indirect}{base class} of another if it is a base @@ -3730,7 +3710,11 @@ \begin{note} Virtual functions support dynamic binding and object-oriented programming. \end{note} A class that declares or inherits a virtual function is -called a \defnadj{polymorphic}{class}. +called a \defnadj{polymorphic}{class}.\footnote{If +all virtual functions are immediate functions, +the class is still polymorphic even though +its internal representation might not otherwise require +any additions for that polymorphic behavior.} \pnum If a virtual member function \tcode{vf} is declared in a class @@ -4062,6 +4046,12 @@ function with a deleted definition.% \indextext{function!virtual|)} +\pnum +A \tcode{consteval} virtual function shall not override +a virtual function that is not \tcode{consteval}. +A \tcode{consteval} virtual function shall not be overridden by +a virtual function that is not \tcode{consteval}. + \pnum If an overriding function specifies contract conditions\iref{dcl.attr.contract}, it shall specify the same list of contract conditions as diff --git a/source/compatibility.tex b/source/compatibility.tex index 7f8c443cb9..adb1ec3dfa 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -64,6 +64,9 @@ The type of a string literal is changed from ``array of \tcode{char}'' to ``array of \tcode{const char}''. +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 from ``array of \textit{some-integer-type}'' to ``array of \tcode{const char16_t}''. @@ -94,7 +97,7 @@ Programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are probably rare. -\rSec2[diff.basic]{\ref{basic}: basic concepts} +\rSec2[diff.basic]{\ref{basic}: basics} \diffref{basic.def} \change \Cpp{} does not have ``tentative definitions'' as in C.\\ @@ -553,7 +556,7 @@ \diffref{dcl.init.aggr} \change In \Cpp{}, designated initialization support is restricted -compared to the corresponding functionality in C. +compared to the corresponding functionality in C\@. In \Cpp{}, designators for non-static data members must be specified in declaration order, @@ -1275,7 +1278,7 @@ \rSec2[diff.cpp03.input.output]{\ref{input.output}: input/output library} -\diffrefs{istream::sentry}{ostream::sentry}, \ref{iostate.flags} +\diffrefs{istream.sentry}{ostream.sentry}, \ref{iostate.flags} \change Specify use of \tcode{explicit} in existing boolean conversion functions. \rationale Clarify intentions, avoid workarounds. \effect @@ -1291,7 +1294,7 @@ \item initializing a \tcode{const bool\&} which would bind to a temporary object. \end{itemize} -\diffref{ios::failure} +\diffref{ios.failure} \change Change base class of \tcode{std::ios_base::failure}. \rationale More detailed error messages. \effect @@ -1345,7 +1348,7 @@ // \tcode{int x[2] = \{ 3'4, 5 \};} --- this International Standard \end{codeblock} -\rSec2[diff.cpp11.basic]{\ref{basic}: basic concepts} +\rSec2[diff.cpp11.basic]{\ref{basic}: basics} \diffref{basic.stc.dynamic.deallocation} \change New usual (non-placement) deallocator. @@ -1792,12 +1795,27 @@ \diffref{lex.key} \change New keywords. \rationale Required for new features. +\begin{itemize} +\item +The \tcode{char8_t} keyword is added to differentiate +the types of ordinary and UTF-8 literals\iref{lex.string}. +\item +The \tcode{concept} keyword is +added to enable the definition of concepts\iref{temp.concept}. +\item +The \tcode{consteval} keyword is added to +declare immediate functions\iref{dcl.constexpr}. +\item The \tcode{requires} keyword is added to introduce constraints through a \grammarterm{requires-clause} or -a \grammarterm{requires-expression}. The \tcode{concept} keyword is -added to enable the definition of concepts\iref{temp.concept}. -\effect -Valid ISO \CppXVII{} code using \tcode{concept} or \tcode{requires} +a \grammarterm{requires-expression}. +\end{itemize} +\effectafteritemize +Valid ISO \CppXVII{} code using +\tcode{char8_t}, +\tcode{concept}, +\tcode{consteval}, +or \tcode{requires} as an identifier is not valid in this International Standard. \diffref{lex.operators} @@ -1815,6 +1833,46 @@ } \end{codeblock} +\diffref{lex.literal} +\change Type of UTF-8 string and character literals. +\rationale Required for new features. +The changed types enable function overloading, template specialization, and +type deduction to distinguish ordinary and UTF-8 string and character literals. +\effect Valid ISO \CppXVII{} code that depends on +UTF-8 string literals having type ``array of \tcode{const char}'' and +UTF-8 character literals having type ``char'' +is not valid in this International Standard. +\begin{codeblock} +const auto *u8s = u8"text"; // \tcode{u8s} previously deduced as \tcode{const char*}; now deduced as \tcode{const char8_t*} +const char *ps = u8s; // ill-formed; previously well-formed + +auto u8c = u8'c'; // \tcode{u8c} previously deduced as \tcode{char}; now deduced as \tcode{char8_t} +char *pc = &u8c; // ill-formed; previously well-formed + +std::string s = u8"text"; // ill-formed; previously well-formed + +void f(const char *s); +f(u8"text"); // ill-formed; previously well-formed + +template struct ct; +template<> struct ct { + using type = char; +}; +ct::type x; // ill-formed; previously well-formed. +\end{codeblock} + +\rSec2[diff.cpp17.basic]{\ref{basic}: basics} + +\diffref{intro.races} +\change Except for the initial release operation, +a release sequence consists solely of atomic read-modify-write operations. +\rationale Removal of rarely used and confusing feature. +\effect If a \tcode{memory_order_release} atomic store is followed +by a \tcode{memory_order_relaxed} store to the same variable by the same thread, +then reading the latter value with a \tcode{memory_order_acquire} load +no longer provides any ``happens before'' guarantees, +even in the absence of intervening stores by another thread. + \rSec2[diff.cpp17.expr]{\ref{expr}: expressions} \diffref{expr.prim.lambda.capture} @@ -2019,6 +2077,65 @@ Translation units compiled against this version of \Cpp{} may be incompatible with translation units compiled against \CppXVII{}, either failing to link or having undefined behavior. +\rSec2[diff.cpp17.alg.reqs]{\ref{algorithms}: algorithms library} + +\diffref{algorithms.requirements} +\change +The number and order of deducible template parameters for algorithm declarations +is now unspecified, instead of being as-declared. +\rationale Increase implementor freedom and allow some function templates +to be implemented as function objects with templated call operators. +\effect +A valid \CppXVII{} program that passes explicit template arguments to +algorithms not explicitly specified to allow such in this version of \Cpp{} +may fail to compile or have undefined behavior. + +\rSec2[diff.cpp17.input.output]{\ref{input.output}: input/output library} + +\diffref{istream.extractors} +\change +Character array extraction only takes array types. +\rationale Increase safety via preventing buffer overflow at compile time. +\effect +Valid \CppXVII{} code may fail to compile in this International Standard: +\begin{codeblock} +auto p = new char[100]; +char q[100]; +std::cin >> std::setw(20) >> p; // ill-formed; previously well-formed +std::cin >> std::setw(20) >> q; // OK +\end{codeblock} + +\diffref{ostream.inserters.character} +\change +Overload resolution for ostream inserters used with UTF-8 literals. +\rationale +Required for new features. +\effect +Valid ISO \CppXVII{} code that passes UTF-8 literals +to \tcode{basic_ostream::\brk{}operator<<} +no longer calls character-related overloads. +\begin{codeblock} +std::cout << u8"text"; // previously called \tcode{operator<<(const char*)} and printed a string; + // now calls \tcode{operator<<(const void*)} and prints a pointer value +std::cout << u8'X'; // previously called \tcode{operator<<(char)} and printed a character; + // now calls \tcode{operator<<(int)} and prints an integer value +\end{codeblock} + +\diffref{fs.class.path} +\change +Return type of filesystem path format observer member functions. +\rationale +Required for new features. +\effect +Valid ISO \CppXVII{} code that depends on the \tcode{u8string()} and +\tcode{generic_u8string()} member functions of \tcode{std::filesystem::path} +returning \tcode{std::string} is not valid in this International Standard. +\begin{codeblock} +std::filesystem::path p; +std::string s1 = p.u8string(); // ill-formed; previously well-formed +std::string s2 = p.generic_u8string(); // ill-formed; previously well-formed +\end{codeblock} + \rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features} \nodiffref diff --git a/source/concepts.tex b/source/concepts.tex index defd96dcb7..6eea186a18 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -178,6 +178,11 @@ concept Assignable = @\seebelow@; // \ref{concept.swappable}, concept \libconcept{Swappable} + namespace ranges { + inline namespace @\unspec@ { + inline constexpr @\unspec@ swap = @\unspec@; + } + } template concept Swappable = @\seebelow@; template @@ -373,15 +378,19 @@ \begin{itemdescr} \pnum -Let \tcode{C} be \tcode{common_reference_t}. Let \tcode{t} be a -function whose return type is \tcode{T}, and let \tcode{u} be a function -whose return type is \tcode{U}. \tcode{\libconcept{CommonReference}} is -satisfied only if: +Let \tcode{C} be \tcode{common_reference_t}. +Let \tcode{t1} and \tcode{t2} be equality-preserving +expressions\iref{concepts.equality} such that +\tcode{decltype((t1))} and \tcode{decltype((t2))} are each \tcode{T}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that +\tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. +\tcode{T} and \tcode{U} model \tcode{\libconcept{CommonReference}} +only if: \begin{itemize} -\item \tcode{C(t())} equals \tcode{C(t())} if and only if \tcode{t()} is an - equality-preserving expression\iref{concepts.equality}. -\item \tcode{C(u())} equals \tcode{C(u())} if and only if \tcode{u()} is an - equality-preserving expression. +\item \tcode{C(t1)} equals \tcode{C(t2)} if and only if + \tcode{t1} equals \tcode{t2}, and +\item \tcode{C(u1)} equals \tcode{C(u2)} if and only if + \tcode{u1} equals \tcode{u2}. \end{itemize} \pnum @@ -407,8 +416,10 @@ template concept Common = Same, common_type_t> && - ConvertibleTo> && - ConvertibleTo> && + requires { + static_cast>(declval()); + static_cast>(declval()); + } && CommonReference< add_lvalue_reference_t, add_lvalue_reference_t> && @@ -421,17 +432,19 @@ \begin{itemdescr} \pnum -Let \tcode{C} be \tcode{common_type_t}. Let -\tcode{t} be a function whose return type is \tcode{T}, and let \tcode{u} be a -function whose return type is \tcode{U}. \tcode{\libconcept{Common}} is -satisfied only if: +Let \tcode{C} be \tcode{common_type_t}. +Let \tcode{t1} and \tcode{t2} be +equality-preserving expressions\iref{concepts.equality} such that +\tcode{decltype((t1))} and \tcode{decltype((t2))} are each \tcode{T}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that +\tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. +\tcode{T} and \tcode{U} model \tcode{\libconcept{Common}} +only if: \begin{itemize} -\item \tcode{C(t())} equals \tcode{C(t())} if and only if - \tcode{t()} is an equality-preserving - expression\iref{concepts.equality}. -\item \tcode{C(u())} equals \tcode{C(u())} if and only if - \tcode{u()} is an equality-preserving - expression\iref{concepts.equality}. +\item \tcode{C(t1)} equals \tcode{C(t2)} if and only if + \tcode{t1} equals \tcode{t2}, and +\item \tcode{C(u1)} equals \tcode{C(u2)} if and only if + \tcode{u1} equals \tcode{u2}. \end{itemize} \pnum @@ -479,8 +492,7 @@ is_lvalue_reference_v && CommonReference&, const remove_reference_t&> && requires(LHS lhs, RHS&& rhs) { - lhs = std::forward(rhs); - requires Same(rhs)), LHS>; + { lhs = std::forward(rhs) } -> Same; }; \end{itemdecl} @@ -524,78 +536,125 @@ \rSec2[concept.swappable]{Concept \libconcept{Swappable}} -\indexlibrary{\idxcode{Swappable}}% -\begin{itemdecl} -template - concept Swappable = is_swappable_v; -\end{itemdecl} - -\begin{itemdescr} \pnum -Let \tcode{a1} and \tcode{a2} denote distinct equal objects of type \tcode{T}, -and let \tcode{b1} and \tcode{b2} similarly denote distinct equal objects of -type \tcode{T}. \tcode{\libconcept{Swappable}} is satisfied only if after -evaluating either \tcode{swap(a1, b1)} or \tcode{swap(b1, a1)} in the context -described below, \tcode{a1} is equal to \tcode{b2} and \tcode{b1} is equal to -\tcode{a2}. +Let \tcode{t1} and \tcode{t2} be equality-preserving expressions that denote +distinct equal objects of type \tcode{T}, and let \tcode{u1} and \tcode{u2} +similarly denote distinct equal objects of type \tcode{U}. +\begin{note} +\tcode{t1} and \tcode{u1} can denote distinct objects, or the same object. +\end{note} +An operation +\term{exchanges the values} denoted by \tcode{t1} and \tcode{u1} if and only +if the operation modifies neither \tcode{t2} nor \tcode{u2} and: +\begin{itemize} +\item If \tcode{T} and \tcode{U} are the same type, the result of the operation + is that \tcode{t1} equals \tcode{u2} and \tcode{u1} equals \tcode{t2}. + +\item If \tcode{T} and \tcode{U} are different types that model + \libconcept{CommonReference}, + the result of the operation is that + \tcode{C(t1)} equals \tcode{C(u2)} + and + \tcode{C(u1)} equals \tcode{C(t2)} + where \tcode{C} is \tcode{common_reference_t}. +\end{itemize} \pnum -The context in which \tcode{swap(a1, b1)} or \tcode{swap(b1, a1)} is evaluated -shall ensure that a binary non-member function named \tcode{swap} is selected via -overload resolution\iref{over.match} on a candidate set that includes: +\indexlibrary{\idxcode{ranges::swap}}% +The name \tcode{ranges::swap} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::swap(E1, E2)} for some subexpressions \tcode{E1} +and \tcode{E2} is expression-equivalent to an expression +\tcode{S} determined as follows: + \begin{itemize} -\item the two \tcode{swap} function templates defined in - \tcode{}\iref{utility} and -\item the lookup set produced by argument-dependent - lookup\iref{basic.lookup.argdep}. +\item + \tcode{S} is \tcode{(void)swap(E1, E2)}\footnote{The name \tcode{swap} is used + here unqualified.} if \tcode{E1} or \tcode{E2} + has class or enumeration type\iref{basic.compound} and that expression is valid, with + overload resolution performed in a context that includes the declarations +\begin{codeblock} + template + void swap(T&, T&) = delete; + template + void swap(T(&)[N], T(&)[N]) = delete; +\end{codeblock} + and does not include a declaration of \tcode{ranges::swap}. + If the function selected by overload resolution does not + exchange the values denoted by + \tcode{E1} and \tcode{E2}, + the program is ill-formed with no diagnostic required. + +\item + Otherwise, if \tcode{E1} and \tcode{E2} + are lvalues of array types\iref{basic.compound} + with equal extent and \tcode{ranges::swap(*E1, *E2)} + is a valid expression, + \tcode{S} is \tcode{(void)ranges::swap_ranges(E1, E2)}, + except that + \tcode{noexcept(S)} is equal to + \tcode{noexcept(\brk{}ranges::swap(*E1, *E2))}. + +\item + Otherwise, if \tcode{E1} and \tcode{E2} are lvalues of the + same type \tcode{T} that models \libconcept{MoveConstructible} and + \libconcept{Assignable}, + \tcode{S} is an expression that exchanges the denoted values. + \tcode{S} is a constant expression if + \begin{itemize} + \item \tcode{T} is a literal type\iref{basic.types}, + \item both \tcode{E1 = std::move(E2)} and \tcode{E2 = std::move(E1)} are + constant subexpressions\iref{defns.const.subexpr}, and + \item the full-expressions of the initializers in the declarations +\begin{codeblock} +T t1(std::move(E1)); +T t2(std::move(E2)); +\end{codeblock} + +are constant subexpressions. + \end{itemize} + \tcode{noexcept(S)} is equal to + \tcode{is_nothrow_move_constructible_v \&\& is_nothrow_move_assignable\-_v}. + +\item + Otherwise, \tcode{ranges::swap(E1, E2)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::swap(E1, E2)} + appears in the immediate context of a template instantiation. + \end{note} \end{itemize} -\end{itemdescr} + +\pnum +\begin{note} +Whenever \tcode{ranges::swap(E1, E2)} is a valid expression, it +exchanges the values denoted by +\tcode{E1} and \tcode{E2} and has type \tcode{void}. +\end{note} + +\indexlibrary{\idxcode{Swappable}}% +\begin{itemdecl} +template + concept Swappable = requires(T& a, T& b) { ranges::swap(a, b); }; +\end{itemdecl} \indexlibrary{\idxcode{SwappableWith}}% \begin{itemdecl} template concept SwappableWith = - is_swappable_with_v && is_swappable_with_v && CommonReference&, const remove_reference_t&> && - is_swappable_with_v && is_swappable_with_v; + requires(T&& t, U&& u) { + ranges::swap(std::forward(t), std::forward(t)); + ranges::swap(std::forward(u), std::forward(u)); + ranges::swap(std::forward(t), std::forward(u)); + ranges::swap(std::forward(u), std::forward(t)); + }; \end{itemdecl} -\begin{itemdescr} -\pnum -Let: -\begin{itemize} -\item \tcode{t1} and \tcode{t2} denote distinct equal objects of type - \tcode{remove_cvref_t}, -\item $E_t$ be an expression that denotes \tcode{t1} such that - \tcode{decltype(($E_t$))} is \tcode{T}, -\item \tcode{u1} and \tcode{u2} similarly denote distinct equal objects of type - \tcode{remove_cvref_t}, -\item $E_u$ be an expression that denotes \tcode{u1} such that - \tcode{decltype(($E_u$))} is \tcode{U}, and -\item \tcode{C} be - % This comfortably fits on one line as a codeblock, but overfills the page as - % tcode. :( - \begin{codeblock} - common_reference_t&, const remove_reference_t&> - \end{codeblock} -\end{itemize} -\tcode{\libconcept{SwappableWith}} is satisfied only if after evaluating -either \tcode{swap($E_t$, $E_u$)} or \tcode{swap($E_u$, $E_t$)} in the context -described above, \tcode{C(t1)} is equal to \tcode{C(u2)} and \tcode{C(u1)} is -equal to \tcode{C(t2)}. - \pnum -The context in which \tcode{swap($E_t$, $E_u$)} or \tcode{swap($E_u$, $E_t$)} -is evaluated shall ensure that a binary non-member function named \tcode{swap} is -selected via overload resolution\iref{over.match} on a candidate set that -includes: -\begin{itemize} -\item the two \tcode{swap} function templates defined in - \tcode{}\iref{utility} and -\item the lookup set produced by argument-dependent - lookup\iref{basic.lookup.argdep}. -\end{itemize} -\end{itemdescr} +\begin{note} +The semantics of the \libconcept{Swappable} and \libconcept{SwappableWith} +concepts are fully defined by the \tcode{ranges::swap} customization point. +\end{note} \pnum \begin{example} @@ -606,18 +665,17 @@ #include #include +namespace ranges = std::ranges; + template U> void value_swap(T&& t, U&& u) { - using std::swap; - swap(std::forward(t), std::forward(u)); // OK: uses ``swappable with'' conditions - // for rvalues and lvalues + ranges::swap(std::forward(t), std::forward(u)); } template void lv_swap(T& t1, T& t2) { - using std::swap; - swap(t1, t2); // OK: uses swappable conditions for -} // lvalues of type \tcode{T} + ranges::swap(t1, t2); +} namespace N { struct A { int m; }; @@ -625,10 +683,9 @@ Proxy proxy(A& a) { return Proxy{ &a }; } void swap(A& x, Proxy p) { - std::swap(x.m, p.a->m); // OK: uses context equivalent to swappable - // conditions for fundamental types + ranges::swap(x.m, p.a->m); } - void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint + void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry requirement } int main() { @@ -757,19 +814,19 @@ requires(const remove_reference_t& b1, const remove_reference_t& b2, const bool a) { requires ConvertibleTo&, bool>; - !b1; requires ConvertibleTo; - b1 && a; requires Same; - b1 || a; requires Same; - b1 && b2; requires Same; - a && b2; requires Same; - b1 || b2; requires Same; - a || b2; requires Same; - b1 == b2; requires ConvertibleTo; - b1 == a; requires ConvertibleTo; - a == b2; requires ConvertibleTo; - b1 != b2; requires ConvertibleTo; - b1 != a; requires ConvertibleTo; - a != b2; requires ConvertibleTo; + { !b1 } -> ConvertibleTo; + { b1 && a } -> Same; + { b1 || a } -> Same; + { b1 && b2 } -> Same; + { a && b2 } -> Same; + { b1 || b2 } -> Same; + { a || b2 } -> Same; + { b1 == b2 } -> ConvertibleTo; + { b1 == a } -> ConvertibleTo; + { a == b2 } -> ConvertibleTo; + { b1 != b2 } -> ConvertibleTo; + { b1 != a } -> ConvertibleTo; + { a != b2 } -> ConvertibleTo; }; \end{itemdecl} @@ -811,10 +868,10 @@ concept @\placeholder{weakly-equality-comparable-with}@ = // \expos requires(const remove_reference_t& t, const remove_reference_t& u) { - t == u; requires Boolean; - t != u; requires Boolean; - u == t; requires Boolean; - u != t; requires Boolean; + { t == u } -> Boolean; + { t != u } -> Boolean; + { u == t } -> Boolean; + { u != t } -> Boolean; }; \end{itemdecl} @@ -888,10 +945,10 @@ EqualityComparable && requires(const remove_reference_t& a, const remove_reference_t& b) { - a < b; requires Boolean; - a > b; requires Boolean b)>; - a <= b; requires Boolean; - a >= b; requires Boolean= b)>; + { a < b } -> Boolean; + { a > b } -> Boolean; + { a <= b } -> Boolean; + { a >= b } -> Boolean; }; \end{itemdecl} @@ -925,14 +982,14 @@ EqualityComparableWith && requires(const remove_reference_t& t, const remove_reference_t& u) { - t < u; requires Boolean; - t > u; requires Boolean u)>; - t <= u; requires Boolean; - t >= u; requires Boolean= u)>; - u < t; requires Boolean; - u > t; requires Boolean t)>; - u <= t; requires Boolean; - u >= t; requires Boolean= t)>; + { t < u } -> Boolean; + { t > u } -> Boolean; + { t <= u } -> Boolean; + { t >= u } -> Boolean; + { u < t } -> Boolean; + { u > t } -> Boolean; + { u <= t } -> Boolean; + { u >= t } -> Boolean; }; \end{itemdecl} @@ -1073,35 +1130,9 @@ template concept Relation = Predicate && Predicate && - CommonReference&, const remove_reference_t&> && - Predicate&, const remove_reference_t&>, - common_reference_t&, const remove_reference_t&>> && Predicate && Predicate; \end{itemdecl} -\begin{itemdescr} -\pnum -Let -\begin{itemize} -\item \tcode{r} be an expression such that \tcode{decltype((r))} is \tcode{R}, -\item \tcode{t} be an expression such that \tcode{decltype((t))} is \tcode{T}, -\item \tcode{u} be an expression such that \tcode{decltype((u))} is \tcode{U}, - and -\item \tcode{C} be - \begin{codeblock} - common_reference_t&, - const remove_reference_t&> - \end{codeblock} -\end{itemize} -\tcode{\libconcept{Relation}} is satisfied only if - -\begin{itemize} -\item \tcode{bool(r(t, u)) == bool(r(C(t), C(u))).} -\item \tcode{bool(r(u, t)) == bool(r(C(u), C(t))).} -\end{itemize} -\end{itemdescr} - \rSec2[concept.strictweakorder]{Concept \libconcept{StrictWeakOrder}} \indexlibrary{\idxcode{Relation}}% diff --git a/source/config.tex b/source/config.tex index 26d6f87b95..174d8ed223 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4778} -\newcommand{\prevdocno}{N4762} +\newcommand{\docno}{N4791} +\newcommand{\prevdocno}{N4778} \newcommand{\cppver}{201703L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index 2312bd54ca..0c392463a8 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -143,20 +143,20 @@ \tcode{X u;} & & & - \postconditions \tcode{u.empty()} & + \ensures \tcode{u.empty()} & constant \\ \rowsep \tcode{X()} & & & - \postconditions \tcode{X().empty()} & + \ensures \tcode{X().empty()} & constant \\ \rowsep \tcode{X(a)} & & & \requires \tcode{T} is \oldconcept{CopyInsertable} - into \tcode{X} (see below).\br \postconditions \tcode{a == X(a)}. & + into \tcode{X} (see below).\br \ensures \tcode{a == X(a)}. & linear \\ \rowsep \tcode{X u(a);}\br @@ -165,14 +165,14 @@ & \requires \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below).\br - \postconditions \tcode{u == a} & + \ensures \tcode{u == a} & linear \\ \rowsep \tcode{X u(rv);}\br \tcode{X u = rv;} & & & - \postconditions \tcode{u} shall be equal to the value that \tcode{rv} had before this construction + \ensures \tcode{u} shall be equal to the value that \tcode{rv} had before this construction & (Note B) \\ \rowsep @@ -183,7 +183,7 @@ had before this assignment & linear \\ \rowsep -\tcode{(\&a)->\~X()} & +\tcode{a.\~X()} & \tcode{void} & & the destructor is applied to every element of \tcode{a}; any memory obtained is deallocated. & @@ -242,7 +242,7 @@ \tcode{r = a} & \tcode{X\&} & & - \postconditions \tcode{r == a}. & + \ensures \tcode{r == a}. & linear \\ \rowsep \tcode{a.size()} & @@ -454,15 +454,21 @@ \pnum \indextext{container!contiguous}% A \defn{contiguous container} -is a container that supports random access iterators\iref{random.access.iterators} -and whose member types \tcode{iterator} and \tcode{const_iterator} -are contiguous iterators\iref{iterator.requirements.general}. +is a container +whose member types \tcode{iterator} and \tcode{const_iterator} +meet the +\oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} and +model \libconcept{ContiguousIterator}\iref{iterator.concept.contiguous}. \pnum \tref{containers.optional.operations} lists operations that are provided for some types of containers but not others. Those containers for which the listed operations are provided shall implement the semantics described in \tref{containers.optional.operations} unless otherwise stated. +If the iterators passed to \tcode{lexicographical_compare} +satisfy the constexpr iterator requirements\iref{iterator.requirements.general} +then the operations described in \tref{containers.optional.operations} +are implemented by constexpr functions. \begin{libreqtab5} {Optional container operations} @@ -633,13 +639,13 @@ \tcode{X u;} & & \requires\ \tcode{A} is \oldconcept{DefaultConstructible}.\br - \postconditions \tcode{u.empty()} returns \tcode{true}, + \ensures \tcode{u.empty()} returns \tcode{true}, \tcode{u.get_allocator() == A()} & constant \\ \rowsep \tcode{X(m)} & & -\postconditions \tcode{u.empty()} returns \tcode{true}, & +\ensures \tcode{u.empty()} returns \tcode{true}, & constant \\ \tcode{X u(m);} & & @@ -650,14 +656,14 @@ \tcode{X u(t, m);} & & \requires\ \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}.\br -\postconditions \tcode{u == t}, \tcode{u.get_allocator() == m} & +\ensures \tcode{u == t}, \tcode{u.get_allocator() == m} & linear \\ \rowsep \tcode{X(rv)}\br \tcode{X u(rv);} & & - \postconditions \tcode{u} shall have the same elements as \tcode{rv} had before this + \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 value of \tcode{rv.get_allocator()} before this construction. & constant \\ \rowsep @@ -667,7 +673,7 @@ & \requires\ \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}.\br - \postconditions \tcode{u} shall have the same elements, + \ensures \tcode{u} shall have the same elements, or copies of the elements, that \tcode{rv} had before this construction, \tcode{u.get_allocator() == m} & constant if \tcode{m ==} \tcode{rv.get_allocator()}, otherwise linear \\ \rowsep @@ -677,7 +683,7 @@ \requires\ \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} and \oldconcept{CopyAssignable}.\br - \postconditions \tcode{a == t} & + \ensures \tcode{a == t} & linear \\ \rowsep \tcode{a = rv} & @@ -690,7 +696,7 @@ \oldconcept{MoveInsertable} into \tcode{X} and \oldconcept{MoveAssignable}. All existing elements of \tcode{a} are either move assigned to or destroyed.\br - \postconditions \tcode{a} shall be equal to the value that \tcode{rv} had before + \ensures \tcode{a} shall be equal to the value that \tcode{rv} had before this assignment. & linear \\ \rowsep @@ -824,7 +830,7 @@ & \requires\ \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{X}.\br - \postconditions \tcode{distance(begin(), end()) == n}\br + \ensures \tcode{distance(begin(), end()) == n}\br Constructs a sequence container with \tcode{n} copies of \tcode{t} \\ \rowsep \tcode{X(i, j)}\br @@ -836,7 +842,7 @@ shall also be \oldconcept{MoveInsertable} into \tcode{X}. Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - \postconditions \tcode{distance(begin(), end()) ==} + \ensures \tcode{distance(begin(), end()) ==} \tcode{distance(i, j)}\br Constructs a sequence container equal to the range \tcode{[i, j)} \\ \rowsep @@ -916,7 +922,7 @@ \tcode{void} & Destroys all elements in \tcode{a}. Invalidates all references, pointers, and iterators referring to the elements of \tcode{a} and may invalidate the past-the-end iterator.\br - \postconditions \tcode{a.empty()} returns \tcode{true}.\br + \ensures \tcode{a.empty()} returns \tcode{true}.\br \complexity Linear. \\ \rowsep \tcode{a.assign(i,j)} & @@ -1847,7 +1853,7 @@ \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 - \postconditions If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, + \ensures If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, \tcode{position} is \tcode{end()}, and \tcode{node} is empty. Otherwise if the insertion took place, \tcode{inserted} is \tcode{true}, \tcode{position} points to the inserted element, and \tcode{node} is empty; @@ -1865,7 +1871,7 @@ pointing to the newly inserted element. If a range containing elements with keys equivalent to \tcode{nh.key()} exists in \tcode{a_eq}, the element is inserted at the end of that range.\br - \postconditions \tcode{nh} is empty. & + \ensures \tcode{nh} is empty. & logarithmic \\ \rowsep \tcode{a.\brk{}insert(\brk{}p, nh)} & @@ -1879,7 +1885,7 @@ with equivalent keys. Always returns the iterator pointing to the element with key equivalent to \tcode{nh.key()}. The element is inserted as close as possible to the position just prior to \tcode{p}.\br - \postconditions \tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. & + \ensures \tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. & logarithmic in general, but amortized constant if the element is inserted right before \tcode{p}. \\ \rowsep @@ -1905,7 +1911,7 @@ 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 - \postconditions Pointers and references to the transferred elements of \tcode{a2} + \ensures Pointers and references to the transferred elements of \tcode{a2} refer to those same elements but as members of \tcode{a}. Iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators into \tcode{a}, not into \tcode{a2}.\br @@ -1945,7 +1951,7 @@ \tcode{a.clear()} & \tcode{void} & \tcode{a.erase(a.begin(),a.end())}\br - \postconditions \tcode{a.empty()} returns \tcode{true}. & + \ensures \tcode{a.empty()} returns \tcode{true}. & linear in \tcode{a.size()}. \\ \rowsep \indexordmem{find}% @@ -2171,9 +2177,10 @@ \pnum \indextext{unordered associative containers!equality function}% -Two values \tcode{k1} and \tcode{k2} of type \tcode{Key} are +Two values \tcode{k1} and \tcode{k2} are considered equivalent if the container's -key equality predicate returns +key equality predicate +\tcode{pred(k1, k2)} is valid and returns \tcode{true} when passed those values. If \tcode{k1} and \tcode{k2} are equivalent, the container's hash function shall return the same value for both. @@ -2250,27 +2257,43 @@ \indextext{unordered associative containers!equivalent keys}% \indextext{requirements!container}% In \tref{HashRequirements}: -\tcode{X} denotes an unordered associative container class, -\tcode{a} denotes a value of type \tcode{X}, -\tcode{a2} denotes a value of a type with nodes compatible with type -\tcode{X} (\tref{containers.node.compat}), -\tcode{b} denotes a possibly const value of type \tcode{X}, -\tcode{a_uniq} denotes a value of type \tcode{X} when \tcode{X} supports unique keys, -\tcode{a_eq} denotes a value of type \tcode{X} when \tcode{X} supports equivalent keys, -\tcode{i} and \tcode{j} denote input iterators that refer to \tcode{value_type}, -\tcode{[i, j)} denotes a valid range, -\tcode{p} and \tcode{q2} denote valid constant iterators to \tcode{a}, -\tcode{q} and \tcode{q1} denote valid dereferenceable constant iterators to \tcode{a}, -\tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, -\tcode{[q1, q2)} denotes a valid range in \tcode{a}, -\tcode{il} denotes a value of type \tcode{initializer_list}, -\tcode{t} denotes a value of type \tcode{X::value_type}, -\tcode{k} denotes a value of type \tcode{key_type}, -\tcode{hf} denotes a possibly const value of type \tcode{hasher}, -\tcode{eq} denotes a possibly const value of type \tcode{key_equal}, -\tcode{n} denotes a value of type \tcode{size_type}, -\tcode{z} denotes a value of type \tcode{float}, -and \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}. +\begin{itemize} +\item \tcode{X} denotes an unordered associative container class, +\item \tcode{a} denotes a value of type \tcode{X}, +\item \tcode{a2} denotes a value of a type with nodes compatible + with type \tcode{X} (\tref{containers.node.compat}), +\item \tcode{b} denotes a possibly const value of type \tcode{X}, +\item \tcode{a_uniq} denotes a value of type \tcode{X} + when \tcode{X} supports unique keys, +\item \tcode{a_eq} denotes a value of type \tcode{X} + when \tcode{X} supports equivalent keys, +\item \tcode{a_tran} denotes a possibly const value of type \tcode{X} + when the \grammarterm{qualified-id} \tcode{X::hasher::transparent_key_equal} + is valid and denotes a type\iref{temp.deduct}, +\item \tcode{i} and \tcode{j} denote input iterators + that refer to \tcode{value_type}, +\item \tcode{[i, j)} denotes a valid range, +\item \tcode{p} and \tcode{q2} denote valid constant iterators to \tcode{a}, +\item \tcode{q} and \tcode{q1} denote + valid dereferenceable constant iterators to \tcode{a}, +\item \tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, +\item \tcode{[q1, q2)} denotes a valid range in \tcode{a}, +\item \tcode{il} denotes a value of type \tcode{initializer_list}, +\item \tcode{t} denotes a value of type \tcode{X::value_type}, +\item \tcode{k} denotes a value of type \tcode{key_type}, +\item \tcode{hf} denotes a possibly const value of type \tcode{hasher}, +\item \tcode{eq} denotes a possibly const value of type \tcode{key_equal}, +\item \tcode{ke} is a value such that + \begin{itemize} + \item \tcode{eq(r1, ke) == eq(ke, r1)} + \item \tcode{hf(r1) == hf(ke)} if \tcode{eq(r1, ke)} is \tcode{true}, and + \item \tcode{(eq(r1, ke) \&\& eq(r1, r2)) == eq(r2, ke)} + \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}. +\end{itemize} % Local command to index names as members of all unordered containers. \newcommand{\indexunordmem}[1]{% @@ -2327,7 +2350,9 @@ % \indexunordmem{key_equal}% \tcode{X::key_equal} -& \tcode{Pred} +& \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 of type \tcode{Key}. \tcode{Pred} is an equivalence relation.% @@ -2607,7 +2632,7 @@ \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 - \postconditions If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, + \ensures If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, \tcode{position} is \tcode{end()}, and \tcode{node} is empty. Otherwise if the insertion took place, \tcode{inserted} is \tcode{true}, \tcode{position} points to the inserted element, and \tcode{node} is empty; @@ -2624,7 +2649,7 @@ \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 - \postconditions \tcode{nh} is empty. & + \ensures \tcode{nh} is empty. & Average case \bigoh{1}, worst case \bigoh{\brk{}\tcode{a_eq.}\brk{}\tcode{size()}}. \\ \rowsep % \tcode{a.insert(q, nh)} & @@ -2639,7 +2664,7 @@ with key equivalent to \tcode{nh.key()}. The iterator \tcode{q} is a hint pointing to where the search should start. Implementations are permitted to ignore the hint.\br - \postconditions \tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. & + \ensures \tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. & Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. \\ \rowsep % \indexunordmem{extract}% @@ -2665,7 +2690,7 @@ 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}.\par - \postconditions Pointers and references to the transferred elements of \tcode{a2} + \ensures Pointers and references to the transferred elements of \tcode{a2} refer to those same elements but as members of \tcode{a}. Iterators referring to the transferred elements and all iterators referring to \tcode{a} will be invalidated, but iterators to elements remaining in \tcode{a2} will @@ -2709,7 +2734,7 @@ \tcode{a.clear()} & \tcode{void} & Erases all elements in the container. - \postconditions \tcode{a.empty()} returns \tcode{true}% + \ensures \tcode{a.empty()} returns \tcode{true}% & Linear in \tcode{a.size()}. \\ \rowsep % @@ -2721,6 +2746,14 @@ & 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 + \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 +\\ \rowsep +% \indexunordmem{count}% \tcode{b.count(k)} & \tcode{size_type} @@ -2728,6 +2761,14 @@ & 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}.% +& Average case + \bigoh{\tcode{a_tran.}\br{}\tcode{count(ke)}}, % avoid overfull + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% \indexunordmem{contains}% \tcode{b.contains(k)} & \tcode{bool} @@ -2735,6 +2776,13 @@ & 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()}% +& Average case \bigoh{1}, + worst case \bigoh{\tcode{a_tran.}\br{}\tcode{size()}}. % avoid overfull +\\ \rowsep +% \indexunordmem{equal_range}% \tcode{b.equal_range(k)} & \tcode{pair}; \br @@ -2746,6 +2794,16 @@ \bigoh{\tcode{b.size()}}. \\ \rowsep % +\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 + \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 \indexunordmem{bucket_count}% \tcode{b.bucket_count()} & \tcode{size_type} @@ -2768,7 +2826,7 @@ \requires \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. - \postconditions 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 % @@ -2847,7 +2905,7 @@ \indexunordmem{rehash}% \tcode{a.rehash(n)} & \tcode{void} -& \postconditions \tcode{a.bucket_count() >= a.size() / a.max_load_factor()} and +& \ensures \tcode{a.bucket_count() >= a.size() / a.max_load_factor()} and \tcode{a.bucket_count() >= n}.% & Average case linear in \tcode{a.size()}, worst case quadratic. \\ \rowsep @@ -2924,6 +2982,24 @@ obtained while it is owned by a \tcode{node_type} are invalidated if the element is successfully inserted. +\pnum +If the \grammarterm{qualified-id} \tcode{Hash::transparent_key_equal} +is valid and denotes a type\iref{temp.deduct}, +then the program is ill-formed if either: +\begin{itemize} +\item + \grammarterm{qualified-id} \tcode{Hash::transparent_key_equal::is_transparent} + is not valid or does not denote a type, or +\item + \tcode{Pred} is a different type than \tcode{equal_to} or + \tcode{Hash::transparent_key_equal}. +\end{itemize} +The member function templates +\tcode{find}, \tcode{count}, \tcode{equal_range}, and \tcode{contains} +shall not participate in overload resolution unless +the \grammarterm{qualified-id} \tcode{Hash::transparent_key_equal} +is valid and denotes a type\iref{temp.deduct}. + \pnum A deduction guide for an unordered associative container shall not participate in overload resolution if any of the following are true: @@ -3009,7 +3085,7 @@ template constexpr bool operator>=(const array& x, const array& y); template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); template class tuple_size; template class tuple_element; @@ -3056,6 +3132,11 @@ void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); + template + void erase(deque& c, const U& value); + template + void erase_if(deque& c, Predicate pred); + namespace pmr { template using deque = std::deque>; @@ -3091,6 +3172,11 @@ void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); + template + void erase(forward_list& c, const U& value); + template + void erase_if(forward_list& c, Predicate pred); + namespace pmr { template using forward_list = std::forward_list>; @@ -3126,6 +3212,11 @@ void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); + template + void erase(list& c, const U& value); + template + void erase_if(list& c, Predicate pred); + namespace pmr { template using list = std::list>; @@ -3161,6 +3252,11 @@ void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); + template + void erase(vector& c, const U& value); + template + void erase_if(vector& c, Predicate pred); + // \ref{vector.bool}, class \tcode{vector} template class vector; @@ -3235,8 +3331,8 @@ // no explicit construct/copy/destroy for aggregate type - void fill(const T& u); - void swap(array&) noexcept(is_nothrow_swappable_v); + constexpr void fill(const T& u); + constexpr void swap(array&) noexcept(is_nothrow_swappable_v); // iterators constexpr iterator begin() noexcept; @@ -3326,7 +3422,7 @@ \indexlibrarymember{array}{fill}% \begin{itemdecl} -void fill(const T& u); +constexpr void fill(const T& u); \end{itemdecl} \begin{itemdescr} @@ -3336,7 +3432,7 @@ \indexlibrarymember{array}{swap}% \begin{itemdecl} -void swap(array& y) noexcept(is_nothrow_swappable_v); +constexpr void swap(array& y) noexcept(is_nothrow_swappable_v); \end{itemdecl} \begin{itemdescr} @@ -3356,7 +3452,7 @@ \indexlibrarymember{array}{swap}% \begin{itemdecl} template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -3790,6 +3886,32 @@ \tcode{T}. \end{itemdescr} +\rSec3[deque.erasure]{Erasure} + +\indexlibrary{\idxcode{erase}!\idxcode{deque}}% +\begin{itemdecl} +template + void erase(deque& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove(c.begin(), c.end(), value), c.end());} +\end{itemdescr} + +\indexlibrary{\idxcode{erase_if}!\idxcode{deque}}% +\begin{itemdecl} +template + void erase_if(deque& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove_if(c.begin(), c.end(), pred), c.end());} +\end{itemdescr} + \rSec2[forwardlist]{Class template \tcode{forward_list}} \rSec3[forwardlist.overview]{Overview} @@ -4475,6 +4597,32 @@ \complexity Linear time. \end{itemdescr} +\rSec3[forward_list.erasure]{Erasure} + +\indexlibrary{\idxcode{erase}!\idxcode{forward_list}}% +\begin{itemdecl} +template + void erase(forward_list& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{erase_if(c, [\&](auto\& elem) { return elem == value; });} +\end{itemdescr} + +\indexlibrary{\idxcode{erase_if}!\idxcode{forward_list}}% +\begin{itemdecl} +template + void erase_if(forward_list& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.remove_if(pred);} +\end{itemdescr} + \rSec2[list]{Class template \tcode{list}} \rSec3[list.overview]{Overview} @@ -5150,6 +5298,32 @@ \tcode{N == size()}. \end{itemdescr} +\rSec3[list.erasure]{Erasure} + +\indexlibrary{\idxcode{erase}!\idxcode{list}}% +\begin{itemdecl} +template + void erase(list& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{erase_if(c, [\&](auto\& elem) { return elem == value; });} +\end{itemdescr} + +\indexlibrary{\idxcode{erase_if}!\idxcode{list}}% +\begin{itemdecl} +template + void erase_if(list& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.remove_if(pred);} +\end{itemdescr} + \rSec2[vector]{Class template \tcode{vector}} \rSec3[vector.overview]{Overview} @@ -5628,6 +5802,32 @@ \tcode{T}. \end{itemdescr} +\rSec3[vector.erasure]{Erasure} + +\indexlibrary{\idxcode{erase}!\idxcode{vector}}% +\begin{itemdecl} +template + void erase(vector& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove(c.begin(), c.end(), value), c.end());} +\end{itemdescr} + +\indexlibrary{\idxcode{erase_if}!\idxcode{vector}}% +\begin{itemdecl} +template + void erase_if(vector& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove_if(c.begin(), c.end(), pred), c.end());} +\end{itemdescr} + \rSec2[vector.bool]{Class \tcode{vector}} \pnum @@ -5864,6 +6064,9 @@ map& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(map& c, Predicate pred); + // \ref{multimap}, class template \tcode{multimap} template, class Allocator = allocator>> @@ -5893,6 +6096,9 @@ multimap& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(multimap& c, Predicate pred); + namespace pmr { template> using map = std::map& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(set& c, Predicate pred); + // \ref{multiset}, class template \tcode{multiset} template, class Allocator = allocator> class multiset; @@ -5969,6 +6178,9 @@ multiset& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(multiset& c, Predicate pred); + namespace pmr { template> using set = std::set>; @@ -6207,7 +6419,7 @@ template, class Allocator = allocator>> - map(initializer_list>, Compare = Compare(), Allocator = Allocator()) + map(initializer_list>, Compare = Compare(), Allocator = Allocator()) -> map; template @@ -6216,7 +6428,7 @@ less<@\placeholder{iter-key-type}@>, Allocator>; template - map(initializer_list>, Allocator) -> map, Allocator>; + map(initializer_list>, Allocator) -> map, Allocator>; // swap template @@ -6491,6 +6703,29 @@ respectively. \end{itemdescr} +\rSec3[map.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{map}}% +\begin{itemdecl} +template + void erase_if(map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[multimap]{Class template \tcode{multimap}} \rSec3[multimap.overview]{Overview} @@ -6703,7 +6938,7 @@ template, class Allocator = allocator>> - multimap(initializer_list>, Compare = Compare(), Allocator = Allocator()) + multimap(initializer_list>, Compare = Compare(), Allocator = Allocator()) -> multimap; template @@ -6712,7 +6947,7 @@ less<@\placeholder{iter-key-type}@>, Allocator>; template - multimap(initializer_list>, Allocator) + multimap(initializer_list>, Allocator) -> multimap, Allocator>; // swap @@ -6793,6 +7028,29 @@ \tcode{true}. \end{itemdescr} +\rSec3[multimap.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{multimap}}% +\begin{itemdecl} +template + void erase_if(multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[set]{Class template \tcode{set}} \rSec3[set.overview]{Overview} @@ -7049,6 +7307,29 @@ \tcode{last - first}. \end{itemdescr} +\rSec3[set.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{set}}% +\begin{itemdecl} +template + void erase_if(set& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[multiset]{Class template \tcode{multiset}} \rSec3[multiset.overview]{Overview} @@ -7303,6 +7584,29 @@ \tcode{last - first}. \end{itemdescr} +\rSec3[multiset.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{multiset}}% +\begin{itemdecl} +template + void erase_if(multiset& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec1[unord]{Unordered associative containers} \rSec2[unord.general]{In general} @@ -7366,6 +7670,12 @@ unordered_multimap& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(unordered_map& c, Predicate pred); + + template + void erase_if(unordered_multimap& c, Predicate pred); + namespace pmr { template& y) noexcept(noexcept(x.swap(y))); + template + void erase_if(unordered_set& c, Predicate pred); + + template + void erase_if(unordered_multiset& c, Predicate pred); + namespace pmr { template, @@ -7486,7 +7802,7 @@ using mapped_type = T; using value_type = pair; using hasher = Hash; - using key_equal = Pred; + using key_equal = @\seeref{unord.req}@; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; @@ -7620,12 +7936,24 @@ key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - bool contains(const key_type& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& k); + template + const_iterator find(const K& k) const; + size_type count(const key_type& k) const; + template + size_type count(const K& k) const; + bool contains(const key_type& k) const; + template + bool contains(const K& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& k); + template + pair equal_range(const K& k) const; // \ref{unord.map.elem}, element access mapped_type& operator[](const key_type& k); @@ -7664,7 +7992,7 @@ template, class Pred = equal_to, class Allocator = allocator>> - unordered_map(initializer_list>, + unordered_map(initializer_list>, typename @\seebelow@::size_type = @\seebelow@, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_map; @@ -7687,16 +8015,16 @@ equal_to<@\placeholder{iter-key-type}@>, Allocator>; template - unordered_map(initializer_list>, typename @\seebelow@::size_type, + unordered_map(initializer_list>, typename @\seebelow@::size_type, Allocator) -> unordered_map, equal_to, Allocator>; template - unordered_map(initializer_list>, Allocator) + unordered_map(initializer_list>, Allocator) -> unordered_map, equal_to, Allocator>; template - unordered_map(initializer_list>, typename @\seebelow@::size_type, Hash, + unordered_map(initializer_list>, typename @\seebelow@::size_type, Hash, Allocator) -> unordered_map, Allocator>; @@ -7989,6 +8317,29 @@ respectively. \end{itemdescr} +\rSec3[unord.map.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{unordered_map}}% +\begin{itemdecl} +template + void erase_if(unordered_map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[unord.multimap]{Class template \tcode{unordered_multimap}}% \indexlibrary{\idxcode{unordered_multimap}} @@ -8033,7 +8384,7 @@ using mapped_type = T; using value_type = pair; using hasher = Hash; - using key_equal = Pred; + using key_equal = @\seeref{unord.req}@; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; @@ -8149,12 +8500,24 @@ key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - bool contains(const key_type& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& k); + template + const_iterator find(const K& k) const; + size_type count(const key_type& k) const; + template + size_type count(const K& k) const; + bool contains(const key_type& k) const; + template + bool contains(const K& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& k); + template + pair equal_range(const K& k) const; // bucket interface size_type bucket_count() const noexcept; @@ -8188,7 +8551,7 @@ template, class Pred = equal_to, class Allocator = allocator>> - unordered_multimap(initializer_list>, + unordered_multimap(initializer_list>, typename @\seebelow@::size_type = @\seebelow@, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multimap; @@ -8212,16 +8575,16 @@ equal_to<@\placeholder{iter-key-type}@>, Allocator>; template - unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, Allocator) -> unordered_multimap, equal_to, Allocator>; template - unordered_multimap(initializer_list>, Allocator) + unordered_multimap(initializer_list>, Allocator) -> unordered_multimap, equal_to, Allocator>; template - unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, Hash, Allocator) -> unordered_multimap, Allocator>; @@ -8325,6 +8688,29 @@ unless \tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} +\rSec3[unord.multimap.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{unordered_multimap}}% +\begin{itemdecl} +template + void erase_if(unordered_multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[unord.set]{Class template \tcode{unordered_set}}% \indexlibrary{\idxcode{unordered_set}} @@ -8361,7 +8747,7 @@ using key_type = Key; using value_type = Key; using hasher = Hash; - using key_equal = Pred; + using key_equal = @\seeref{unord.req}@; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; @@ -8476,12 +8862,24 @@ key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - bool contains(const key_type& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& k); + template + const_iterator find(const K& k) const; + size_type count(const key_type& k) const; + template + size_type count(const K& k) const; + bool contains(const key_type& k) const; + template + bool contains(const K& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& k); + template + pair equal_range(const K& k) const; // bucket interface size_type bucket_count() const noexcept; @@ -8608,6 +9006,29 @@ \complexity Average case linear, worst case quadratic. \end{itemdescr} +\rSec3[unord.set.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{unordered_set}}% +\begin{itemdecl} +template + void erase_if(unordered_set& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec2[unord.multiset]{Class template \tcode{unordered_multiset}}% \indexlibrary{\idxcode{unordered_multiset}} @@ -8651,7 +9072,7 @@ using key_type = Key; using value_type = Key; using hasher = Hash; - using key_equal = Pred; + using key_equal = @\seeref{unord.req}@; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; @@ -8765,12 +9186,24 @@ key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - bool contains(const key_type& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& k); + template + const_iterator find(const K& k) const; + size_type count(const key_type& k) const; + template + size_type count(const K& k) const; + bool contains(const key_type& k) const; + template + bool contains(const K& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& k); + template + pair equal_range(const K& k) const; // bucket interface size_type bucket_count() const noexcept; @@ -8896,6 +9329,29 @@ \pnum\complexity Average case linear, worst case quadratic. \end{itemdescr} +\rSec3[unord.multiset.erasure]{Erasure} + +\indexlibrary{\idxcode{erase_if}!\idxcode{unordered_multiset}}% +\begin{itemdecl} +template + void erase_if(unordered_multiset& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +\end{codeblock} +\end{itemdescr} + \rSec1[container.adaptors]{Container adaptors} \rSec2[container.adaptors.general]{In general} @@ -9799,20 +10255,6 @@ template class span; - // \ref{span.comparison}, comparison operators - template - constexpr bool operator==(span l, span r); - template - constexpr bool operator!=(span l, span r); - template - constexpr bool operator<(span l, span r); - template - constexpr bool operator>(span l, span r); - template - constexpr bool operator<=(span l, span r); - template - constexpr bool operator>=(span l, span r); - // \ref{span.objectrep}, views of object representation template span - constexpr bool operator==(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return equal(l.begin(), l.end(), r.begin(), r.end());} -\end{itemdescr} - -\indexlibrary{\idxcode{operator"!=}!\idxcode{span}}% -\begin{itemdecl} -template - constexpr bool operator!=(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return !(l == r);} -\end{itemdescr} - -\indexlibrary{\idxcode{operator<}!\idxcode{span}}% -\begin{itemdecl} -template - constexpr bool operator<(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); -\end{codeblock} -\end{itemdescr} - -\indexlibrary{\idxcode{operator>}!\idxcode{span}}% -\begin{itemdecl} -template - constexpr bool operator>(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return (r < l);} -\end{itemdescr} - -\indexlibrary{\idxcode{operator<=}!\idxcode{span}}% -\begin{itemdecl} -template - constexpr bool operator<=(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return !(r < l);} -\end{itemdescr} - -\indexlibrary{\idxcode{operator>=}!\idxcode{span}}% -\begin{itemdecl} -template - constexpr bool operator>=(span l, span r); -\end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return !(l < r);} -\end{itemdescr} \rSec3[span.objectrep]{Views of object representation} diff --git a/source/declarations.tex b/source/declarations.tex index 1717ebebd6..7a7b78af4b 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -253,6 +253,7 @@ \terminal{friend}\br \terminal{typedef}\br \terminal{constexpr}\br + \terminal{consteval}\br \terminal{inline} \end{bnf} @@ -269,9 +270,11 @@ same type. \pnum -Each \grammarterm{decl-specifier} shall appear at most once in a complete -\grammarterm{decl-specifier-seq}, except that -\tcode{long} may appear twice. +Each \grammarterm{decl-specifier} +shall appear at most once in a complete \grammarterm{decl-specifier-seq}, +except that \tcode{long} may appear twice. +The \tcode{constexpr} and \tcode{consteval} \grammarterm{decl-specifier}{s} +shall not both appear in a \grammarterm{decl-specifier-seq}. \pnum \indextext{ambiguity!declaration type}% @@ -367,8 +370,8 @@ 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 names of variables of namespace -or block scope and to the names of static data members. +to the declaration of a variable of namespace +or block scope 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 @@ -376,8 +379,8 @@ \pnum \indextext{restriction!\idxcode{static}}% -The \tcode{static} specifier can be applied only to names of variables and -functions and to anonymous unions\iref{class.union.anon}. There can be no +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 \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 @@ -392,9 +395,9 @@ \pnum \indextext{restriction!\idxcode{extern}}% -The \tcode{extern} specifier can be applied only to the names of variables -and functions. The \tcode{extern} specifier cannot be used in the -declaration of class members or function parameters. +The \tcode{extern} specifier shall be applied only to the declaration of a variable +or function. The \tcode{extern} specifier shall not be used in the +declaration of a class member or function parameter. \indextext{\idxcode{extern}!linkage of}% \indextext{consistency!linkage}% For the linkage of a name declared with an \tcode{extern} specifier, @@ -550,20 +553,21 @@ \begin{bnf} \nontermdef{typedef-name}\br - identifier + identifier\br + simple-template-id \end{bnf} A name declared with the \tcode{typedef} specifier becomes a -\grammarterm{typedef-name}. Within the scope of its declaration, a -\grammarterm{typedef-name} is syntactically equivalent to a keyword and -names the type associated with the identifier in the way described in -\ref{dcl.decl}. +\grammarterm{typedef-name}. +A \grammarterm{typedef-name} names +the type associated with the \grammarterm{identifier}\iref{dcl.decl} +or \grammarterm{simple-template-id}\iref{temp}; \indextext{declaration!typedef@\tcode{typedef} as type}% \indextext{equivalence!type}% \indextext{synonym!type name as}% -A \grammarterm{typedef-name} is thus a synonym for another type. A +a \grammarterm{typedef-name} is thus a synonym for another type. A \grammarterm{typedef-name} does not introduce a new type the way a class -declaration\iref{class.name} or enum declaration does. +declaration\iref{class.name} or enum declaration\iref{dcl.enum} does. \begin{example} After @@ -677,18 +681,20 @@ \end{example} \pnum -\begin{note} \indextext{class name!\idxcode{typedef}}% -A \grammarterm{typedef-name} that names a class type, or a cv-qualified -version thereof, is also a \grammarterm{class-name}\iref{class.name}. If -a \grammarterm{typedef-name} is used to identify the subject of an +A \grammarterm{simple-template-id} is only a \grammarterm{typedef-name} +if its \grammarterm{template-name} names +an alias template or a template \grammarterm{template-parameter}. +\begin{note} +A \grammarterm{simple-template-id} that names a class template specialization +is a \grammarterm{class-name}\iref{class.name}. +If a \grammarterm{typedef-name} is used to identify the subject of an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}, a class definition\iref{class}, a constructor declaration\iref{class.ctor}, or a destructor declaration\iref{class.dtor}, the program is ill-formed. \end{note} \begin{example} - \begin{codeblock} struct S { S(); @@ -733,17 +739,21 @@ \indextext{specifier!\idxcode{constexpr}} \pnum -The \tcode{constexpr} specifier shall be applied only to the definition of -a variable or variable template or -the declaration of a -function or function template. -A function or static data member declared with the \tcode{constexpr} -specifier is implicitly an inline function or variable\iref{dcl.inline}. +The \tcode{constexpr} specifier shall be applied only to +the definition of a variable or variable template or +the declaration of a function or function template. +The \tcode{consteval} specifier shall be applied only to +the declaration of a function or function template. +A function or static data member +declared with the \tcode{constexpr} or \tcode{consteval} specifier +is implicitly an inline function or variable\iref{dcl.inline}. If any declaration of a function or function template has -a \tcode{constexpr} specifier, -then all its declarations shall contain the \tcode{constexpr} specifier. \begin{note} An -explicit specialization can differ from the template declaration with respect to the -\tcode{constexpr} specifier. \end{note} +a \tcode{constexpr} or \tcode{consteval} specifier, +then all its declarations shall contain the same specifier. +\begin{note} +An explicit specialization can differ from the template declaration +with respect to the \tcode{constexpr} or \tcode{consteval} specifier. +\end{note} \begin{note} Function parameters cannot be declared \tcode{constexpr}.\end{note} \begin{example} @@ -773,12 +783,17 @@ \end{example} \pnum -A \tcode{constexpr} specifier used in the declaration of a function that is not a -constructor declares that -function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. Similarly, a -\tcode{constexpr} specifier used in -a constructor declaration declares that constructor to be a -\defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}. +A \tcode{constexpr} or \tcode{consteval} specifier +used in the declaration of a function that is not a constructor +declares that function to be +a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. +Similarly, a \tcode{constexpr} or \tcode{consteval} specifier used in +a constructor declaration declares that constructor to be +a \defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}. +A function or constructor declared with the \tcode{consteval} specifier +is called an \defn{immediate function}. +A destructor, an allocation function, or a deallocation function +shall not be declared with the \tcode{consteval} specifier. \pnum \indextext{specifier!\idxcode{constexpr}!function} @@ -794,22 +809,20 @@ each of its parameter types shall be a literal type; \item -its \grammarterm{function-body} shall be -\tcode{= delete}, \tcode{= default}, or -a \grammarterm{compound-statement} -that does not contain - +its \grammarterm{function-body} shall not contain \begin{itemize} \item an \grammarterm{asm-definition}, \item a \tcode{goto} statement, \item an identifier label\iref{stmt.label}, -\item a \grammarterm{try-block}, or \item a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed. \end{itemize} - +\begin{note} +A \grammarterm{function-body} that is \tcode{= delete} or \tcode{= default} +contains none of the above. +\end{note} \end{itemize} \begin{example} @@ -850,10 +863,7 @@ the class shall not have any virtual base classes; \item -each of the parameter types shall be a literal type; - -\item -its \grammarterm{function-body} shall not be a \grammarterm{function-try-block}. +each of the parameter types shall be a literal type. \end{itemize} In addition, either its \grammarterm{function-body} shall be @@ -948,8 +958,9 @@ \end{itemize} \pnum -The \tcode{constexpr} specifier has no -effect on the type of a constexpr function or a constexpr constructor. \begin{example} +The \tcode{constexpr} and \tcode{consteval} specifiers have no +effect on the type of a constexpr function or a constexpr constructor. +\begin{example} \begin{codeblock} constexpr int bar(int x, int y) // OK { return x + y + x*y; } @@ -982,8 +993,8 @@ \indextext{specifier!\idxcode{inline}} \pnum -The \tcode{inline} specifier can be applied only to the declaration -or definition of a variable or function. +The \tcode{inline} specifier shall be applied only to the declaration +of a variable or function. \pnum \indextext{specifier!\idxcode{inline}}% @@ -1247,8 +1258,11 @@ \nontermdef{simple-type-specifier}\br \opt{nested-name-specifier} type-name\br nested-name-specifier \terminal{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 @@ -1260,27 +1274,19 @@ \terminal{unsigned}\br \terminal{float}\br \terminal{double}\br - \terminal{void}\br - \terminal{auto}\br - decltype-specifier + \terminal{void} \end{bnf} \begin{bnf} \nontermdef{type-name}\br class-name\br enum-name\br - typedef-name\br - simple-template-id -\end{bnf} - -\begin{bnf} -\nontermdef{decltype-specifier}\br - \terminal{decltype} \terminal{(} expression \terminal{)}\br - \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)} + typedef-name \end{bnf} \pnum \indextext{type specifier!\idxcode{char}}% +\indextext{type specifier!\idxcode{char8_t}}% \indextext{type specifier!\idxcode{char16_t}}% \indextext{type specifier!\idxcode{char32_t}}% \indextext{type specifier!\idxcode{wchar_t}}% @@ -1293,11 +1299,9 @@ \indextext{type specifier!\idxcode{float}}% \indextext{type specifier!\idxcode{double}}% \indextext{type specifier!\idxcode{void}}% -\indextext{type specifier!\idxcode{auto}}% -\indextext{type specifier!\idxcode{decltype}}% \indextext{\idxgram{type-name}}% \indextext{\idxgram{lambda-introducer}}% -The \grammarterm{simple-type-specifier} \tcode{auto} +A \grammarterm{placeholder-type-specifier} is a placeholder for a type to be deduced\iref{dcl.spec.auto}. \indextext{deduction!class template arguments}% @@ -1325,10 +1329,14 @@ \hdstyle{Specifier(s)} & \hdstyle{Type} \\ \capsep \grammarterm{type-name} & the type named \\ \grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\ -\grammarterm{template-name} & placeholder for a type to be deduced\\ +\grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\ +\grammarterm{placeholder-type-specifier} + & the type as defined in~\ref{dcl.spec.auto}\\ +\grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\ \tcode{char} & ``\tcode{char}'' \\ \tcode{unsigned char} & ``\tcode{unsigned char}'' \\ \tcode{signed char} & ``\tcode{signed char}'' \\ +\tcode{char8_t} & ``\tcode{char8_t}'' \\ \tcode{char16_t} & ``\tcode{char16_t}'' \\ \tcode{char32_t} & ``\tcode{char32_t}'' \\ \tcode{bool} & ``\tcode{bool}'' \\ @@ -1360,10 +1368,6 @@ \tcode{double} & ``\tcode{double}'' \\ \tcode{long double} & ``\tcode{long double}'' \\ \tcode{void} & ``\tcode{void}'' \\ -\tcode{auto} & placeholder for a type to be deduced\\ -\tcode{decltype(auto)} & placeholder for a type to be deduced\\ -\tcode{decltype(}\grammarterm{expression}\tcode{)} - & the type as defined below\\ \end{simpletypetable} \pnum @@ -1375,6 +1379,100 @@ forces \tcode{char} objects to be signed; it is redundant in other contexts. \end{note} +\rSec3[dcl.type.elab]{Elaborated type specifiers}% +\indextext{type specifier!elaborated}% +\indextext{\idxcode{typename}}% +\indextext{type specifier!\idxcode{enum}} + +\begin{bnf} +\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 +\end{bnf} + +\pnum +\indextext{class name!elaborated}% +\indextext{name!elaborated!\idxcode{enum}}% +An \grammarterm{attribute-specifier-seq} shall not appear in an \grammarterm{elaborated-type-specifier} +unless the latter is the sole constituent of a declaration. +If an \grammarterm{elaborated-type-specifier} is the sole constituent of a +declaration, the declaration is ill-formed unless it is an explicit +specialization\iref{temp.expl.spec}, an explicit +instantiation\iref{temp.explicit} or it has one of the following +forms: + +\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{;} +\end{ncsimplebnf} + +In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains +to the class being declared; the attributes in the +\grammarterm{attribute-specifier-seq} are thereafter considered attributes of +the class whenever it is named. + +\pnum +\begin{note} +\ref{basic.lookup.elab} describes how name lookup proceeds for the +\grammarterm{identifier} in an \grammarterm{elaborated-type-specifier}. +\end{note} +If the \grammarterm{identifier} or \grammarterm{simple-template-id} +resolves to a \grammarterm{class-name} or +\grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier} +introduces it into the declaration the same way a +\grammarterm{simple-type-specifier} introduces +its \grammarterm{type-name}\iref{dcl.type.simple}. +If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a +\grammarterm{typedef-name} (\ref{dcl.typedef}, \ref{temp.names}), +the \grammarterm{elaborated-type-specifier} is ill-formed. +\begin{note} +This implies that, within a class template with a template +\grammarterm{type-parameter} \tcode{T}, the declaration + +\begin{codeblock} +friend class T; +\end{codeblock} + +is ill-formed. However, the similar declaration \tcode{friend T;} is allowed\iref{class.friend}. +\end{note} + +\pnum +The \grammarterm{class-key} or \tcode{enum} keyword +present in the +\grammarterm{elaborated-type-specifier} shall agree in kind with the +declaration to which the name in the +\grammarterm{elaborated-type-specifier} refers. This rule also applies to +the form of \grammarterm{elaborated-type-specifier} that declares a +\grammarterm{class-name} or friend class since it can be construed +as referring to the definition of the class. Thus, in any +\grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword +shall be +used to refer to an enumeration\iref{dcl.enum}, the \tcode{union} +\grammarterm{class-key} shall be used to refer to a union\iref{class}, +and either the \tcode{class} or \tcode{struct} +\grammarterm{class-key} shall be used to refer to a class\iref{class} +declared using the \tcode{class} or \tcode{struct} +\grammarterm{class-key}. \begin{example} + +\begin{codeblock} +enum class E { a, b }; +enum E x = E::a; // OK +\end{codeblock} +\end{example} + +\rSec3[dcl.type.decltype]{Decltype specifiers}% +\indextext{type specifier!\idxcode{decltype}}% + +\begin{bnf} +\nontermdef{decltype-specifier}\br + \terminal{decltype} \terminal{(} expression \terminal{)} +\end{bnf} + \pnum \indextext{type specifier!\idxcode{decltype}}% For an expression \tcode{e}, the type denoted by \tcode{decltype(e)} is defined as follows: @@ -1430,7 +1528,8 @@ \end{note} \pnum -If the operand of a \grammarterm{decltype-specifier} is a prvalue, +If the operand of a \grammarterm{decltype-specifier} is a prvalue +and is not a (possibly parenthesized) immediate invocation\iref{expr.const}, the temporary materialization conversion is not applied\iref{conv.rval} and no result object is provided for the prvalue. The type of the prvalue may be incomplete or an abstract class type. @@ -1478,103 +1577,30 @@ \end{codeblock} \end{example} -\rSec3[dcl.type.elab]{Elaborated type specifiers}% -\indextext{type specifier!elaborated}% -\indextext{\idxcode{typename}}% -\indextext{type specifier!\idxcode{enum}} +\rSec3[dcl.spec.auto]{Placeholder type specifiers}% +\indextext{type specifier!\idxcode{auto}} +\indextext{type specifier!\idxcode{decltype(auto)}}% \begin{bnf} -\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 +\nontermdef{placeholder-type-specifier}\br + \opt{type-constraint} \terminal{auto}\br + \opt{type-constraint} \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)} \end{bnf} \pnum -\indextext{class name!elaborated}% -\indextext{name!elaborated!\idxcode{enum}}% -An \grammarterm{attribute-specifier-seq} shall not appear in an \grammarterm{elaborated-type-specifier} -unless the latter is the sole constituent of a declaration. -If an \grammarterm{elaborated-type-specifier} is the sole constituent of a -declaration, the declaration is ill-formed unless it is an explicit -specialization\iref{temp.expl.spec}, an explicit -instantiation\iref{temp.explicit} or it has one of the following -forms: - -\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{;} -\end{ncsimplebnf} - -In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains -to the class being declared; the attributes in the -\grammarterm{attribute-specifier-seq} are thereafter considered attributes of -the class whenever it is named. +A \grammarterm{placeholder-type-specifier} +designates a placeholder type that will be replaced later by deduction +from an initializer. \pnum -\ref{basic.lookup.elab} describes how name lookup proceeds for the -\grammarterm{identifier} in an \grammarterm{elaborated-type-specifier}. If the -\grammarterm{identifier} resolves to a \grammarterm{class-name} or -\grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier} -introduces it into the declaration the same way a -\grammarterm{simple-type-specifier} introduces its \grammarterm{type-name}. If -the \grammarterm{identifier} resolves to a -\grammarterm{typedef-name} or the \grammarterm{simple-template-id} resolves to -an alias template specialization, -the -\grammarterm{elaborated-type-specifier} is ill-formed. -\begin{note} -This implies that, within a class template with a template -\grammarterm{type-parameter} \tcode{T}, the declaration - -\begin{codeblock} -friend class T; -\end{codeblock} - -is ill-formed. However, the similar declaration \tcode{friend T;} is allowed\iref{class.friend}. -\end{note} - -\pnum -The \grammarterm{class-key} or \tcode{enum} keyword -present in the -\grammarterm{elaborated-type-specifier} shall agree in kind with the -declaration to which the name in the -\grammarterm{elaborated-type-specifier} refers. This rule also applies to -the form of \grammarterm{elaborated-type-specifier} that declares a -\grammarterm{class-name} or friend class since it can be construed -as referring to the definition of the class. Thus, in any -\grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword -shall be -used to refer to an enumeration\iref{dcl.enum}, the \tcode{union} -\grammarterm{class-key} shall be used to refer to a union\iref{class}, -and either the \tcode{class} or \tcode{struct} -\grammarterm{class-key} shall be used to refer to a class\iref{class} -declared using the \tcode{class} or \tcode{struct} -\grammarterm{class-key}. \begin{example} - -\begin{codeblock} -enum class E { a, b }; -enum E x = E::a; // OK -\end{codeblock} -\end{example} - -\rSec3[dcl.spec.auto]{The \tcode{auto} specifier}% -\indextext{type specifier!\idxcode{auto}} - -\pnum -The \tcode{auto} and \tcode{decltype(auto)} \grammarterm{type-specifier}{s} -are used to -designate a placeholder type that will be replaced later by deduction -from an initializer. The \tcode{auto} -\grammarterm{type-specifier} is also used to -introduce a function type having a \grammarterm{trailing-return-type} or to -signify that a lambda is a generic lambda\iref{expr.prim.lambda}. -The \tcode{auto} \grammarterm{type-specifier} is also used to introduce a -structured binding declaration\iref{dcl.struct.bind}. +A \grammarterm{placeholder-type-specifier} of the form +\opt{\grammarterm{type-constraint}} \tcode{auto} +can be used in the \grammarterm{decl-specifier-seq} of +a \grammarterm{parameter-declaration} of +a function declaration or \grammarterm{lambda-expression} and +signifies that the function is +an abbreviated function template\iref{dcl.fct} or +the lambda is a generic lambda\iref{expr.prim.lambda}. \pnum The placeholder type can appear with a function declarator in the @@ -1590,11 +1616,11 @@ of the function\iref{stmt.if}. \pnum -The type of a variable declared using \tcode{auto} or \tcode{decltype(auto)} is +The type of a variable declared using a placeholder type is deduced from its initializer. This use is allowed in an initializing declaration\iref{dcl.init} of a variable. -\tcode{auto} or \tcode{decltype(auto)} shall appear as one of the +The placeholder type shall appear as one of the \grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} and the \grammarterm{decl-specifier-seq} @@ -1622,6 +1648,9 @@ auto h(); // OK: \tcode{h}'s return type will be deduced when it is defined \end{codeblock} \end{example} +The \tcode{auto} \grammarterm{type-specifier} +can also be used to introduce +a structured binding declaration\iref{dcl.struct.bind}. \pnum A placeholder type can also be used @@ -1634,7 +1663,7 @@ in a \grammarterm{template-parameter}\iref{temp.param}. \pnum -A program that uses \tcode{auto} or \tcode{decltype(auto)} in a context not +A program that uses a placeholder type in a context not explicitly allowed in this subclause is ill-formed. \pnum @@ -1691,7 +1720,8 @@ \end{example} \pnum -Return type deduction for a function template with a placeholder in its +Return type deduction for a templated entity +that is a function or function template with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a \tcode{return} statement with a non-type-dependent operand. \begin{note} Therefore, any use of a specialization of the function template will @@ -1803,7 +1833,8 @@ In the case of a \tcode{return} statement with no operand or with an operand of type \tcode{void}, \tcode{T} shall be either -\tcode{decltype(auto)} or \cv{}~\tcode{auto}. +\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)} or +\cv{}~\opt{\grammarterm{type-constraint}} \tcode{auto}. \pnum If the deduction is for a \tcode{return} statement @@ -1811,13 +1842,15 @@ the program is ill-formed. \pnum -If the placeholder is the \tcode{auto} \grammarterm{type-specifier}, the -deduced type +If the \grammarterm{placeholder-type-specifier} is of the form +\opt{\grammarterm{type-constraint}} \tcode{auto}, +the deduced type $\mathtt{T}'$ replacing \tcode{T} is determined using the rules for template argument deduction. Obtain \tcode{P} from -\tcode{T} by replacing the occurrences of \tcode{auto} with either a new -invented type template parameter \tcode{U} or, +\tcode{T} by replacing the occurrences of +\opt{\grammarterm{type-constraint}} \tcode{auto} with either +a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with \tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules of template argument deduction from a function call\iref{temp.deduct.call}, @@ -1849,7 +1882,8 @@ \end{example} \pnum -If the placeholder is the \tcode{decltype(auto)} \grammarterm{type-specifier}, +If the \grammarterm{placeholder-type-specifier} is of the form +\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)}, \tcode{T} shall be the placeholder alone. The type deduced for \tcode{T} is determined as described in~\ref{dcl.type.simple}, as though @@ -1873,6 +1907,12 @@ \end{codeblock} \end{example} +\pnum +For a \grammarterm{placeholder-type-specifier} with +a \grammarterm{type-constraint}, +if the type deduced for the placeholder does not satisfy its +immediately-declared constraint\iref{temp}, the program is ill-formed. + \rSec3[dcl.type.class.deduct]{Deduced class template specialization types} \indextext{deduction!class template arguments}% @@ -3272,7 +3312,7 @@ However, the first argument must be of a type that can be converted to a \tcode{const} -\tcode{char*} +\tcode{char*}. \end{example} \begin{note} The standard header @@ -3512,6 +3552,91 @@ A \term{non-template function} is a function that is not a function template specialization. \begin{note} A function template is not a function. \end{note} +\pnum +\indextext{abbreviated!template function|see{template, function, abbreviated}}% +An \defnx{abbreviated function template}{template!function!abbreviated} +is a function declaration whose \grammarterm{parameter-type-list} includes +one or more placeholders\iref{dcl.spec.auto}. +An abbreviated function template is equivalent to +a function template\iref{temp.over.link} +whose \grammarterm{template-parameter-list} includes +one invented type \grammarterm{template-parameter} +for each occurrence of a placeholder type in +the \grammarterm{decl-specifier-seq} of +a \grammarterm{parameter-declaration} in +the function's parameter-type-list, in order of appearance. +For a \grammarterm{placeholder-type-specifier} of the form \tcode{auto}, +the invented parameter is +an unconstrained \grammarterm{type-parameter}. +For a \grammarterm{placeholder-type-specifier} of the form +\grammarterm{type-constraint} \tcode{auto}, +the invented parameter is a \grammarterm{type-parameter} with +that \grammarterm{type-constraint}. +The invented type \grammarterm{template-parameter} is +a template parameter pack +if the corresponding \grammarterm{parameter-declaration} +declares a function parameter pack\iref{dcl.fct}. +If the placeholder contains \tcode{decltype(auto)}, +the program is ill-formed. +The adjusted function parameters of an abbreviated function template +are derived from the \grammarterm{parameter-declaration-clause} by +replacing each occurrence of a placeholder with +the name of the corresponding invented \grammarterm{template-parameter}. +\begin{example} +\begin{codeblock} +template concept C1 = /* ... */; +template concept C2 = /* ... */; +template concept C3 = /* ... */; + +void g1(const C1 auto*, C2 auto&); +void g2(C1 auto&...); +void g3(C3 auto...); +void g4(C3 auto); +\end{codeblock} + +These declarations are functionally equivalent (but not equivalent) to +the following declarations. +\begin{codeblock} +template void g1(const T*, U&); +template void g2(Ts&...); +template void g3(Ts...); +template void g4(T); +\end{codeblock} + +Abbreviated function templates can be specialized like all function templates. +\begin{codeblock} +template<> void g1(const int*, const double&); // OK, specialization of \tcode{g1} +\end{codeblock} +\end{example} + +\pnum +An abbreviated function template can have a \grammarterm{template-head}. +The invented \grammarterm{template-parameters} are +appended to the \grammarterm{template-parameter-list} after +the explicitly declared \grammarterm{template-parameters}. +\begin{example} +\begin{codeblock} +template concept C = /* ... */; + +template + void g(T x, U y, C auto z); +\end{codeblock} + +This is functionally equivalent to each of the following two declarations. +\begin{codeblock} +template + void g(T x, U y, W z); + +template + requires C && C + void g(T x, U y, W z); +\end{codeblock} +\end{example} + +\pnum +A function declaration at block scope +shall not declare an abbreviated function template. + \pnum A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} containing an ellipsis shall only @@ -3525,7 +3650,6 @@ template parameter pack; see~\ref{temp.param}. A function parameter pack is a pack expansion\iref{temp.variadic}. \begin{example} - \begin{codeblock} template void f(T (* ...t)(int, int)); @@ -4171,7 +4295,7 @@ \begin{itemize} \item If an indeterminate value of -unsigned narrow character type\iref{basic.fundamental} +unsigned ordinary character type\iref{basic.fundamental} or \tcode{std::byte} type\iref{cstddef.syn} is produced by the evaluation of: \begin{itemize} @@ -4179,7 +4303,7 @@ \item the right operand of a comma expression\iref{expr.comma}, \item the operand of a cast or conversion~(\ref{conv.integral}, \ref{expr.type.conv}, \ref{expr.static.cast}, \ref{expr.cast}) to an -unsigned narrow character type +unsigned ordinary character type or \tcode{std::byte} type\iref{cstddef.syn}, or \item a discarded-value expression\iref{expr.prop}, \end{itemize} @@ -4187,25 +4311,25 @@ \item If an indeterminate value of -unsigned narrow character type +unsigned ordinary character type or \tcode{std::byte} type is produced by the evaluation of the right operand of a simple assignment operator\iref{expr.ass} whose first operand is an lvalue of -unsigned narrow character type +unsigned ordinary character type or \tcode{std::byte} type, an indeterminate value replaces the value of the object referred to by the left operand. \item -If an indeterminate value of unsigned narrow character type is produced by the +If an indeterminate value of unsigned ordinary character type is produced by the evaluation of the initialization expression when initializing an object of -unsigned narrow character type, that object is initialized to an indeterminate +unsigned ordinary character type, that object is initialized to an indeterminate value. \item If an indeterminate value of -unsigned narrow character type +unsigned ordinary character type or \tcode{std::byte} type is produced by the evaluation of the initialization expression when initializing an object of @@ -4293,6 +4417,7 @@ If the destination type is a reference type, see~\ref{dcl.init.ref}. \item If the destination type is an array of characters, +an array of \tcode{char8_t}, an array of \tcode{char16_t}, an array of \tcode{char32_t}, or an array of @@ -4356,9 +4481,14 @@ If the conversion cannot be done or is ambiguous, the initialization is ill-formed. \item +Otherwise, if the initialization is direct-initialization, +the source type is \tcode{std::nullptr_t}, and +the destination type is \tcode{bool}, +the initial value of the object being initialized is \tcode{false}. +\item Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. -Standard conversions\iref{conv} will be used, if necessary, +A standard conversion sequence\iref{conv} will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. @@ -4497,6 +4627,18 @@ where \placeholder{D} is the \grammarterm{designated-initializer-clause} naming a member of the anonymous union object. There shall be only one such \grammarterm{designated-initializer-clause}. +\begin{example} +\begin{codeblock} +struct C { + union { + int a; + const char* p; + }; + int x; +} c = { .a = 1, .x = 3 }; +\end{codeblock} +initializes \tcode{c.a} with 1 and \tcode{c.x} with 3. +\end{example} \item Otherwise, the element is copy-initialized from the corresponding \grammarterm{initializer-clause} @@ -4511,7 +4653,6 @@ \begin{note} If an initializer is itself an initializer list, the element is list-initialized, which will result in a recursive application of the rules in this subclause if the element is an aggregate. \end{note} -\end{itemize} \begin{example} \begin{codeblock} struct A { @@ -4555,6 +4696,7 @@ \tcode{d2.b3} with 42, \tcode{d2.d} with 4. \end{example} +\end{itemize} \pnum For a non-union aggregate, @@ -4649,10 +4791,8 @@ \grammarterm{initializer-list} containing \tcode{n} -\grammarterm{initializer-clause}{s}, -where -\tcode{n} -shall be greater than zero, is defined as having +\grammarterm{initializer-clause}{s} +is defined as having \tcode{n} elements\iref{dcl.array}. \begin{example} @@ -4666,11 +4806,9 @@ as a one-dimensional array that has three elements since no size was specified and there are three initializers. \end{example} -An empty initializer list -\tcode{\{\}} -shall not be used as the \grammarterm{initializer-clause} -for an array of unknown bound.\footnote{The syntax provides for empty -initializer lists, +An array of unknown bound shall not be initialized with +an empty \grammarterm{braced-init-list} \tcode{\{\}}.% +\footnote{The syntax provides for empty \grammarterm{braced-init-list}{s}, but nonetheless \Cpp{} does not have zero length arrays.} \begin{note} A default member initializer does not determine the bound for a member @@ -4982,13 +5120,17 @@ \indextext{initialization!character array} \pnum -An array of narrow character type\iref{basic.fundamental}, +An array of ordinary character type\iref{basic.fundamental}, +\tcode{char8_t} array, \tcode{char16_t} array, \tcode{char32_t} array, or \tcode{wchar_t} array -can be initialized by a -narrow string literal, \tcode{char16_t} string literal, \tcode{char32_t} string -literal, or wide string literal, +can be initialized by +an ordinary string literal, +\tcode{char8_t} string literal, +\tcode{char16_t} string literal, +\tcode{char32_t} string literal, or +wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces\iref{lex.string}. \indextext{initialization!character array}% @@ -5868,9 +6010,9 @@ \pnum An explicitly-defaulted function that is not defined as deleted may be declared -\tcode{constexpr} only if it would have been implicitly declared as -\tcode{constexpr}. If -a function is explicitly defaulted on its first declaration, +\tcode{constexpr} or \tcode{consteval} only +if it would have been implicitly declared as \tcode{constexpr}. +If a function is explicitly defaulted on its first declaration, it is implicitly considered to be \tcode{constexpr} if the implicit declaration would be. @@ -6019,7 +6161,7 @@ \pnum A structured binding declaration introduces the \grammarterm{identifier}{s} -\tcode{v}$_0$, \tcode{v}$_1$, \tcode{v}$_2$, ... +$\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc$ of the \grammarterm{identifier-list} as names\iref{basic.scope.declarative} of \defn{structured binding}{s}. @@ -6117,7 +6259,7 @@ the number of elements in the \grammarterm{identifier-list} shall be equal to the number of non-static data members of \tcode{E}. Designating the non-static data members of \tcode{E} as -\tcode{m}$_0$, \tcode{m}$_1$, \tcode{m}$_2$, ... +$\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 @@ -6166,7 +6308,7 @@ \begin{bnf} \nontermdef{opaque-enum-declaration}\br - enum-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier \opt{enum-base} \terminal{;} + enum-key \opt{attribute-specifier-seq} enum-head-name \opt{enum-base} \terminal{;} \end{bnf} \begin{bnf} @@ -6219,7 +6361,7 @@ \end{example} \end{note} -If an \grammarterm{opaque-enum-declaration} contains +If the \grammarterm{enum-head-name} of an \grammarterm{opaque-enum-declaration} contains a \grammarterm{nested-name-specifier}, the declaration shall be an explicit specialization\iref{temp.expl.spec}. @@ -6232,7 +6374,7 @@ \tcode{enum struct} are semantically equivalent; an enumeration type declared with one of these is a \defnadj{scoped}{enumeration}, and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}. -The optional \grammarterm{identifier} shall not be omitted in the declaration of a scoped enumeration. +The optional \grammarterm{enum-head-name} shall not be omitted in the declaration of a scoped enumeration. The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} shall name an integral type; any cv-qualification is ignored. An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall @@ -6275,12 +6417,18 @@ underlying type as in the original declaration. \pnum -If the \grammarterm{enum-key} is followed by a -\grammarterm{nested-name-specifier}, the \grammarterm{enum-specifier} shall +If an \grammarterm{enum-head-name} contains a +\grammarterm{nested-name-specifier}, +it shall not begin with a \grammarterm{decltype-specifier} and +the enclosing \grammarterm{enum-specifier} +or \grammarterm{opaque-enum-declaration} shall refer to an enumeration that was previously declared directly in the class or -namespace to which the \grammarterm{nested-name-specifier} refers (i.e., neither +namespace to which the \grammarterm{nested-name-specifier} refers, +or in an element of the inline namespace +set\iref{namespace.def} of that namespace (i.e., neither inherited nor introduced by a \grammarterm{using-declaration}), and the -\grammarterm{enum-specifier} shall appear in a namespace enclosing the previous +\grammarterm{enum-specifier} or \grammarterm{opaque-enum-declaration} +shall appear in a namespace enclosing the previous declaration. \pnum @@ -6347,21 +6495,14 @@ value 0. \pnum -\indextext{signed integer representation!ones' complement}% \indextext{signed integer representation!two's complement}% -\indextext{signed integer representation!signed magnitude}% For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, -for an enumeration where $e_\text{min}$ is the smallest enumerator and -$e_\text{max}$ is the largest, the values of the enumeration are the -values in the range $b_\text{min}$ to $b_\text{max}$, defined as follows: Let $K$ -be 1 for a two's complement representation and 0 for a ones' complement -or sign-magnitude representation. $b_\text{max}$ is the smallest value -greater than or equal to $max(|e_\text{min}| - K, |e_\text{max}|)$ and equal to -$2^M-1$, where $M$ is a non-negative integer. $b_\text{min}$ is zero if -$e_\text{min}$ is non-negative and $-(b_\text{max}+K)$ otherwise. The size of the -smallest bit-field large enough to hold all the values of the -enumeration type is $max(M,1)$ if $b_\text{min}$ is zero and $M+1$ otherwise. +the values of the enumeration are the values representable by +a hypothetical integer types with minimal range exponent $M$ +such that all enumerators can be represented. +The width of the smallest bit-field large enough to hold all the values of the +enumeration type is $M$. It is possible to define an enumeration that has values not defined by any of its enumerators. If the \grammarterm{enumerator-list} is empty, the values of the enumeration are as if the enumeration had a single enumerator with @@ -6455,20 +6596,6 @@ \end{codeblock} \end{example} -\pnum -If an \grammarterm{enum-head} contains a \grammarterm{nested-name-specifier}, -the \grammarterm{enum-specifier} shall refer to an enumeration -that was previously declared directly in the class or namespace -to which the \grammarterm{nested-name-specifier} refers, or -in an element of the inline namespace set\iref{namespace.def} -of that namespace (i.e., not merely inherited or introduced by a -\grammarterm{using-declaration}), and -the \grammarterm{enum-specifier} shall appear in -a namespace enclosing the previous declaration. -In such cases, the \grammarterm{nested-name-specifier} -of the \grammarterm{enum-head} of the definition -shall not begin with a \grammarterm{decltype-specifier}. - \rSec1[basic.namespace]{Namespaces}% \indextext{namespaces|(} @@ -6512,13 +6639,13 @@ \begin{bnf} \nontermdef{nested-namespace-definition}\br - \terminal{namespace} enclosing-namespace-specifier \terminal{::} identifier \terminal{\{} namespace-body \terminal{\}} + \terminal{namespace} enclosing-namespace-specifier \terminal{::} \opt{\terminal{inline}} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{enclosing-namespace-specifier}\br identifier\br - enclosing-namespace-specifier \terminal{::} identifier + enclosing-namespace-specifier \terminal{::} \opt{\terminal{inline}} identifier \end{bnf} \begin{bnf} @@ -6632,18 +6759,20 @@ \grammarterm{namespace-body} \tcode{B} is equivalent to \begin{codeblock} -namespace E { namespace I { B } } +namespace E { @\opt{inline}@ namespace I { B } } \end{codeblock} +where the optional \tcode{inline} is present if and only if +the \grammarterm{identifier} \tcode{I} is preceded by \tcode{inline}. \begin{example} \begin{codeblock} -namespace A::B::C { +namespace A::inline B::C { int i; } \end{codeblock} The above has the same effect as: \begin{codeblock} namespace A { - namespace B { + inline namespace B { namespace C { int i; } @@ -8001,11 +8130,11 @@ may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, or an \grammarterm{exception-declaration}\iref{except.handle}. -An \grammarterm{alignment-specifier} may also be applied to the declaration or -definition of a class (in an +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 or definition of an enumeration (in an +declaration of an enumeration (in an \grammarterm{opaque-enum-declaration} or \grammarterm{enum-head}, respectively\iref{dcl.enum}). An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}. @@ -8339,52 +8468,6 @@ 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. -Additional access restrictions apply to names appearing in -a contract condition of a member function of class \tcode{C}: -\begin{itemize} -\item Friendship is not considered\iref{class.friend}. -\item For a contract condition of a public member function, -no member of \tcode{C} or of an enclosing class of \tcode{C} is accessible -unless it is a public member of \tcode{C}, -or a member of a base class -accessible as a public member of \tcode{C}\iref{class.access.base}. -\item For a contract condition of a protected member function, -no member of \tcode{C} or of an enclosing class of \tcode{C} is accessible -unless it is a public or protected member of \tcode{C}, -or a member of a base class -accessible as a public or protected member of \tcode{C}. -\end{itemize} -For names appearing in a contract condition of a non-member function, -friendship is not considered. -\begin{example} -\begin{codeblock} -class X { -public: - int v() const; - void f() [[expects: x > 0]]; // error: \tcode{x} is private - void g() [[expects: v() > 0]]; // OK - friend void r(int z) [[expects: z > 0]]; // OK - friend void s(int z) [[expects: z > x]]; // error: \tcode{x} is private -protected: - int w(); - void h() [[expects: x > 0]]; // error: \tcode{x} is private - void i() [[ensures: y > 0]]; // OK - void j() [[ensures: w() > 0]]; // OK - int y; -private: - void k() [[expects: x > 0]]; // OK - int x; -}; - -class Y : public X { -public: - void a() [[expects: v() > 0]]; // OK - void b() [[ensures: w() > 0]]; // error: \tcode{w} is protected -protected: - void c() [[expects: w() > 0]]; // OK -}; -\end{codeblock} -\end{example} \pnum A precondition is checked by evaluating its predicate @@ -8525,14 +8608,13 @@ The \defn{violation handler} of a program is a function of type ``\opt{\tcode{noexcept}} function of (lvalue reference to \tcode{const std::contract_violation}) -returning \tcode{void}'', and is specified in an -\impldef{specification of violation handler} manner. +returning \tcode{void}''. The violation handler is invoked when the predicate of a checked contract evaluates to \tcode{false} (called a \defn{contract violation}). There should be no programmatic way of setting or modifying the violation handler. -It is \impldef{argument for violation handler} +It is \impldef{establishing of and argument for violation handler} how the violation handler is established for a program and how the \tcode{std::contract_violation}\iref{support.contract.cviol} argument value diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 5018ef47ec..29b67330c1 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -106,7 +106,7 @@ \tcode{logic_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -122,7 +122,7 @@ \tcode{logic_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -157,7 +157,7 @@ \tcode{domain_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -173,7 +173,7 @@ \tcode{domain_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -207,7 +207,7 @@ \tcode{invalid_argument}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -223,7 +223,7 @@ \tcode{invalid_argument}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -259,7 +259,7 @@ \tcode{length_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -275,7 +275,7 @@ \tcode{length_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -311,7 +311,7 @@ \tcode{out_of_range}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -327,7 +327,7 @@ \tcode{out_of_range}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -362,7 +362,7 @@ \tcode{runtime_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -378,7 +378,7 @@ \tcode{runtime_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -413,7 +413,7 @@ \tcode{range_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -429,7 +429,7 @@ \tcode{range_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -463,7 +463,7 @@ \tcode{overflow_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -479,7 +479,7 @@ \tcode{overflow_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -513,7 +513,7 @@ \tcode{underflow_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} @@ -529,7 +529,7 @@ \tcode{underflow_error}. \pnum -\postconditions +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} @@ -1215,7 +1215,7 @@ \effects Constructs an object of type \tcode{error_code}. \pnum -\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&system_category()}. +\ensures \tcode{val_ == 0} and \tcode{cat_ == \&system_category()}. \end{itemdescr} \indexlibrary{\idxcode{error_code}!constructor}% @@ -1228,7 +1228,7 @@ \effects Constructs an object of type \tcode{error_code}. \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} \indexlibrary{\idxcode{error_code}!constructor}% @@ -1242,7 +1242,7 @@ \effects Constructs an object of type \tcode{error_code}. \pnum -\postconditions \tcode{*this == make_error_code(e)}. +\ensures \tcode{*this == make_error_code(e)}. \pnum \remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak @@ -1258,7 +1258,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} \indexlibrarymember{operator=}{error_code}% @@ -1269,7 +1269,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{*this == make_error_code(e)}. +\ensures \tcode{*this == make_error_code(e)}. \pnum \returns \tcode{*this}. @@ -1286,7 +1286,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{value() == 0} and \tcode{category() == system_category()}. +\ensures \tcode{value() == 0} and \tcode{category() == system_category()}. \end{itemdescr} @@ -1418,7 +1418,7 @@ \effects Constructs an object of type \tcode{error_condition}. \pnum -\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}. +\ensures \tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}. \end{itemdescr} \indexlibrary{\idxcode{error_condition}!constructor}% @@ -1431,7 +1431,7 @@ \effects Constructs an object of type \tcode{error_condition}. \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} \indexlibrary{\idxcode{error_condition}!constructor}% @@ -1445,7 +1445,7 @@ \effects Constructs an object of type \tcode{error_condition}. \pnum -\postconditions \tcode{*this == make_error_condition(e)}. +\ensures \tcode{*this == make_error_condition(e)}. \pnum \remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak @@ -1462,7 +1462,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures \tcode{val_ == val} and \tcode{cat_ == \&cat}. \end{itemdescr} \indexlibrarymember{operator=}{error_condition}% @@ -1473,7 +1473,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{*this == make_error_condition(e)}. +\ensures \tcode{*this == make_error_condition(e)}. \pnum \returns \tcode{*this}. @@ -1490,7 +1490,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{value() == 0} and \tcode{category() == generic_category()}. +\ensures \tcode{value() == 0} and \tcode{category() == generic_category()}. \end{itemdescr} \rSec3[syserr.errcondition.observers]{Observers} @@ -1702,7 +1702,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \tcode{code() == ec} and +\ensures \tcode{code() == ec} and \tcode{string(what()).find(what_arg) != string::npos}. \end{itemdescr} @@ -1716,7 +1716,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \tcode{code() == ec} and +\ensures \tcode{code() == ec} and \tcode{string(what()).find(what_arg) != string::npos}. \end{itemdescr} @@ -1730,7 +1730,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \tcode{code() == ec}. +\ensures \tcode{code() == ec}. \end{itemdescr} \indexlibrary{\idxcode{system_error}!constructor}% @@ -1743,7 +1743,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak +\ensures \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak \tcode{string(what()).find(what_arg) != string::npos}. \end{itemdescr} @@ -1757,7 +1757,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak +\ensures \raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak \tcode{string(what()).find(what_arg) != string::npos}. \end{itemdescr} @@ -1771,7 +1771,7 @@ \effects Constructs an object of class \tcode{system_error}. \pnum -\postconditions \tcode{code() == error_code(ev, ecat)}. +\ensures \tcode{code() == error_code(ev, ecat)}. \end{itemdescr} \indexlibrarymember{code}{system_error}% diff --git a/source/expressions.tex b/source/expressions.tex index 0d4993009c..a98f375a57 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -139,7 +139,7 @@ \begin{itemize} \item A \defn{glvalue} is an expression whose evaluation determines the identity of an object, bit-field, or function. \item A \defn{prvalue} is an expression whose evaluation initializes an object or a bit-field, -or computes the value of the operand of an operator, +or computes the value of an operand of an operator, as specified by the context in which it appears. \item An \defn{xvalue} is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime). \item An \defn{lvalue} is a glvalue that is not an xvalue. @@ -631,9 +631,9 @@ \item If \tcode{T} is \cv{}~\tcode{std::nullptr_t}, the result is a null pointer constant\iref{conv.ptr}. \begin{note} -Since no value is fetched from memory, -there is no side effect for a volatile access\iref{intro.execution}, and -an inactive member of a union\iref{class.union} may be accessed. +Since the conversion does not access the object to which the glvalue refers, +there is no side effect even if \tcode{T} is volatile-qualified\iref{intro.execution}, and +the glvalue can refer to an inactive member of a union\iref{class.union}. \end{note} \item Otherwise, if \tcode{T} has a class @@ -877,29 +877,19 @@ integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type. -\pnum -\indextext{conversion!to unsigned}% -If the destination type is unsigned, the resulting value is the least -unsigned integer congruent to the source integer (modulo $2^n$ where $n$ -is the number of bits used to represent the unsigned type). -\indextext{signed integer representation!two's complement}% -\begin{note} -In a two's complement representation, this conversion is conceptual and -there is no change in the bit pattern (if there is no truncation). -\end{note} - -\pnum -\indextext{conversion!to signed}% -If the destination type is signed, the value is unchanged if it can be -represented in the destination type; otherwise, -the value is \impldef{value of result of unsigned to signed conversion}. - \pnum \indextext{conversion!bool@\tcode{bool}}% If the destination type is \tcode{bool}, see~\ref{conv.bool}. If the source type is \tcode{bool}, the value \tcode{false} is converted to zero and the value \tcode{true} is converted to one. +\pnum +\indextext{conversion!to unsigned}% +\indextext{conversion!to signed}% +Otherwise, the result is the unique value of the destination type +that is congruent to the source integer modulo $2^N$, +where $N$ is the range exponent of the destination type. + \pnum The conversions allowed as integral promotions are excluded from the set of integral conversions. @@ -1068,10 +1058,7 @@ A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type \tcode{bool}. A zero value, null pointer value, or null member pointer value is converted to \tcode{false}; any -other value is converted to \tcode{true}. For -direct-initialization\iref{dcl.init}, a prvalue of type -\tcode{std::nullptr_t} can be converted to a prvalue of type -\tcode{bool}; the resulting value is \tcode{false}. +other value is converted to \tcode{true}. \indextext{conversion!standard|)} @@ -1099,7 +1086,7 @@ converted to \tcode{float}. \item Otherwise, the integral promotions\iref{conv.prom} shall be -performed on both operands.\footnote{As a consequence, operands of type \tcode{bool}, \tcode{char16_t}, +performed on both operands.\footnote{As a consequence, operands of type \tcode{bool}, \tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, \tcode{wchar_t}, or an enumerated type are converted to some integral type.} Then the following rules shall be applied to the promoted operands: @@ -1279,6 +1266,12 @@ \end{example} \end{itemize} +\pnum +An \grammarterm{id-expression} +that denotes an immediate function\iref{dcl.constexpr} +shall appear as a subexpression of an immediate invocation or +in an immediate function context\iref{expr.const}. + \pnum An \grammarterm{id-expression} that denotes the specialization of a concept\iref{temp.concept} @@ -1335,7 +1328,7 @@ operator-function-id\br conversion-function-id\br literal-operator-id\br - \terminal{\~} class-name\br + \terminal{\~} type-name\br \terminal{\~} decltype-specifier\br template-id \end{bnf} @@ -1350,9 +1343,10 @@ For \grammarterm{operator-function-id}{s}, see~\ref{over.oper}; for \grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for \grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for -\grammarterm{template-id}{s}, see~\ref{temp.names}. A \grammarterm{class-name} -or \grammarterm{decltype-specifier} -prefixed by \tcode{\~} denotes a destructor; see~\ref{class.dtor}. +\grammarterm{template-id}{s}, see~\ref{temp.names}. +A \grammarterm{type-name} or \grammarterm{decltype-specifier} +prefixed by \tcode{\~} denotes the destructor of the type so named; +see~\ref{expr.prim.id.dtor}. Within the definition of a non-static member function, an \grammarterm{identifier} that names a non-static member is transformed to a class member access expression~(\ref{class.mfct.non-static}). @@ -1447,15 +1441,12 @@ point in its potential scope\iref{basic.scope.class}. \end{note} Where -\grammarterm{class-name} \tcode{::\~}~\grammarterm{class-name} is used, -the two \grammarterm{class-name}{s} shall refer to the same class; this -notation names the destructor\iref{class.dtor}. -The form \tcode{\~}~\grammarterm{decltype-specifier} also denotes the destructor, -but it shall not be used as the \grammarterm{unqualified-id} in a \grammarterm{qualified-id}. -\begin{note} -A \grammarterm{typedef-name} that names a class is a -\grammarterm{class-name}\iref{class.name}. -\end{note} +\grammarterm{type-name} \tcode{::\~}~\grammarterm{type-name} is used, +the two \grammarterm{type-name}{s} shall refer to the same type +(ignoring cv-qualifications); +this notation denotes the destructor of the type so named\iref{expr.prim.id.dtor}. +The \grammarterm{unqualified-id} in a \grammarterm{qualified-id} +shall not be of the form \tcode{\~}\grammarterm{decltype-specifier}. \pnum The \grammarterm{nested-name-specifier} \tcode{::} names the global namespace. @@ -1486,6 +1477,43 @@ \grammarterm{qualified-id} occurs and in the context of the class denoted by the \grammarterm{nested-name-specifier}. +\rSec3[expr.prim.id.dtor]{Destruction} + +\pnum +\indextext{expression!destructor call}% +\indextext{expression!pseudo-destructor call}% +An \grammarterm{id-expression} that denotes the destructor of a type \tcode{T} +names the destructor of \tcode{T} +if \tcode{T} is a class type\iref{class.dtor}, +otherwise the \grammarterm{id-expression} is said +to name a \defn{pseudo-destructor}. + +\pnum +If the \grammarterm{id-expression} names a pseudo-destructor, +\tcode{T} shall be a scalar type and +the \grammarterm{id-expression} shall appear +as the right operand of a class member access\iref{expr.ref} that forms +the \grammarterm{postfix-expression} of a function call\iref{expr.call}. +\begin{note} +Such a call has no effect. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct C { }; +void f() { + C * pc = new C; + using C2 = C; + pc->C::~C2(); // OK, destroys \tcode{*pc} + C().C::~C(); // undefined behavior: temporary of type \tcode{C} destroyed twice + using T = int; + 0 .T::~T(); // OK, no effect + 0.T::~T(); // error: \tcode{0.} is a floating-point literal\iref{lex.fcon} +} +\end{codeblock} +\end{example} + \rSec2[expr.prim.lambda]{Lambda expressions}% \indextext{expression!lambda|(} @@ -1532,7 +1560,7 @@ \pnum In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, each \grammarterm{decl-specifier} -shall either be \tcode{mutable} or \tcode{constexpr}. +shall be one of \tcode{mutable}, \tcode{constexpr}, or \tcode{consteval}. \begin{note} The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}. \end{note} @@ -1556,8 +1584,9 @@ \pnum A lambda is a \defn{generic lambda} -if the \tcode{auto} \grammarterm{type-specifier} appears as one of the -\grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} of a +if there is a \grammarterm{decl-specifier} that is +a \grammarterm{placeholder-type-specifier} in +the \grammarterm{decl-specifier-seq} of a \grammarterm{parameter-declaration} of the \grammarterm{lambda-expression}, or if the lambda has a \grammarterm{template-parameter-list}. \begin{example} @@ -1598,33 +1627,25 @@ type. \pnum -The closure type for a non-generic \grammarterm{lambda-expression} has a public -inline function call operator\iref{over.call} whose parameters and return type +The closure type for a \grammarterm{lambda-expression} has a public +inline function call operator (for a non-generic lambda) or +function call operator template (for a generic lambda)\iref{over.call} +whose parameters and return type are described by the \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} and \grammarterm{trailing-return-type} -respectively. -For a generic lambda, the closure type has a public inline function call -operator member template\iref{temp.mem} whose +respectively, and whose \grammarterm{template-parameter-list} consists of -the specified \grammarterm{template-parameter-list}, if any, -to which is appended one invented type -\grammarterm{template-parameter} for each occurrence of \tcode{auto} in the -lambda's \grammarterm{parameter-declaration-clause}, in order of appearance. -The invented type \grammarterm{template-parameter} is a template parameter pack if -the corresponding \grammarterm{parameter-declaration} declares a function -parameter pack\iref{dcl.fct}. The return type and function parameters of the -function call operator template are derived from the -\grammarterm{lambda-expression}{'s} \grammarterm{trailing-return-type} and -\grammarterm{parameter-declaration-clause} by replacing each occurrence of -\tcode{auto} in the \grammarterm{decl-specifier}{s} of the -\grammarterm{parameter-declaration-clause} with the name of the corresponding -invented \grammarterm{template-parameter}. +the specified \grammarterm{template-parameter-list}, if any. The \grammarterm{requires-clause} of the function call operator template is the \grammarterm{requires-clause} immediately following \tcode{<}~\grammarterm{template-parameter-list}{}~\tcode{>}, if any. The trailing \grammarterm{requires-clause} of the function call operator or operator template is the \grammarterm{requires-clause} following the \grammarterm{lambda-declarator}, if any. +\begin{note} +The function call operator for a generic lambda might be +an abbreviated function template\iref{dcl.fct}. +\end{note} \begin{example} \begin{codeblock} auto glambda = [](auto a, auto&& b) { return a < b; }; @@ -1658,8 +1679,12 @@ The function call operator or any given operator template specialization is a constexpr function if either the corresponding \grammarterm{lambda-expression}{'s} -\grammarterm{parameter-declaration-clause} is followed by \tcode{constexpr}, or +\grammarterm{parameter-declaration-clause} +is followed by \tcode{constexpr} or \tcode{consteval}, or it satisfies the requirements for a constexpr function\iref{dcl.constexpr}. +It is an immediate function\iref{dcl.constexpr} +if the corresponding \grammarterm{lambda-expression}{'s} +\grammarterm{parameter-declaration-clause} is followed by \tcode{consteval}. \begin{note} Names referenced in the \grammarterm{lambda-declarator} are looked up in the context in which the \grammarterm{lambda-expression} appears. \end{note} @@ -1705,8 +1730,10 @@ \end{example} \pnum +\begin{note} The function call operator or operator template may be constrained\iref{temp.constr.decl} -by a \grammarterm{constrained-parameter}\iref{temp.param}, a \grammarterm{requires-clause}\iref{temp}, +by a \grammarterm{type-constraint}\iref{temp.param}, +a \grammarterm{requires-clause}\iref{temp}, or a trailing \grammarterm{requires-clause}\iref{dcl.decl}. \begin{example} \begin{codeblock} @@ -1716,12 +1743,13 @@ auto f = [] requires C2 (T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3 { - // \tcode{T2} is a constrained parameter, + // \tcode{T2} is constrained by a \grammarterm{type-constraint}. // \tcode{T1} and \tcode{T2} are constrained by a \grammarterm{requires-clause}, and // \tcode{T2} and the type of \tcode{a4} are constrained by a trailing \grammarterm{requires-clause}. }; \end{codeblock} \end{example} +\end{note} \pnum The closure type for a non-generic \grammarterm{lambda-expression} with no @@ -1737,7 +1765,9 @@ is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the closure type's function call operator. \tcode{F} is a constexpr function -if the function call operator 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. 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 @@ -2600,7 +2630,7 @@ \begin{bnf} \nontermdef{return-type-requirement}\br trailing-return-type\br - \terminal{->} \opt{cv-qualifier-seq} constrained-parameter \opt{cv-qualifier-seq} \opt{abstract-declarator} + \terminal{->} type-constraint \end{bnf} \pnum @@ -2610,47 +2640,59 @@ semantic properties proceed in the following order: \begin{itemize} -\item Substitution of template arguments (if any) +\item +Substitution of template arguments (if any) into the \grammarterm{expression} is performed. -\item If the \tcode{noexcept} specifier is present, +\item +If the \tcode{noexcept} specifier is present, \tcode{E} shall not be a potentially-throwing expression\iref{except.spec}. -\item If the \grammarterm{return-type-requirement} is present, then: +\item +If the \grammarterm{return-type-requirement} is present, then: \begin{itemize} -\item Substitution of template arguments (if any) +\item +Substitution of template arguments (if any) into the \grammarterm{return-type-requirement} is performed. -\item If the \grammarterm{return-type-requirement} is a -\grammarterm{trailing-return-type}, +\item +If the \grammarterm{return-type-requirement} is a +\grammarterm{trailing-return-type}\iref{dcl.decl}, %%% FIXME: is -> shall be \tcode{E} is implicitly convertible to the type named by the \grammarterm{trailing-return-type}. If conversion fails, the enclosing \grammarterm{requires-expression} is \tcode{false}. -\item If the \grammarterm{return-type-requirement} -starts with a \grammarterm{constrained-parameter}\iref{temp.param}, -the \grammarterm{expression} is deduced against -an invented function template \tcode{F} -using the rules in \ref{temp.deduct.call}. -\tcode{F} is a \tcode{void} function template -with a single type template parameter \tcode{T} -declared with the \grammarterm{constrained-parameter}. -A \grammarterm{cv-qualifier-seq} \cv{} is formed -as the union of \tcode{const} and \tcode{volatile} specifiers -around the \grammarterm{constrained-parameter}. -\tcode{F} has a single parameter -whose \grammarterm{type-specifier} is \cv{}~\tcode{T} -followed by the \grammarterm{abstract-declarator}. -%%% FIXME: Remove this; if deduction fails, the construct should -%%% be ill-formed. -If deduction fails, -the enclosing \grammarterm{requires-expression} is \tcode{false}. +\item +If the \grammarterm{return-type-requirement} +is of the form \tcode{->} \grammarterm{type-constraint}, then +the contextually-determined type being constrained +is \tcode{decltype((E))}. +The immediately-declared constraint\iref{temp} of \tcode{decltype((E))} +shall be satisfied. +\begin{example} +Given concepts \tcode{C} and \tcode{D}, +\begin{codeblock} +requires { + { E1 } -> C; + { E2 } -> @D@; +}; +\end{codeblock} +is equivalent to +\begin{codeblock} +requires { + E1; requires C; + E2; requires @D@; +}; +\end{codeblock} +(including in the case where $n$ is zero). +\end{example} \end{itemize} \end{itemize} +\pnum \begin{example} \begin{codeblock} template concept C1 = requires(T x) { @@ -2675,32 +2717,13 @@ \tcode{typename T::inner}. \begin{codeblock} -template concept C3 = requires (T t, U u) { - t == u; -}; -template concept C4 = requires(T x) { - {*x} -> C3 const&; -}; -\end{codeblock} -The \grammarterm{compound-requirement} -requires that \tcode{*x} be deduced -as an argument for the invented function: -\begin{codeblock} -template X> void f(X const&); -\end{codeblock} -In this case, deduction only succeeds if -an expression of the type deduced for \tcode{X} -can be compared to an \tcode{int} -with the \tcode{==} operator. - -\begin{codeblock} -template concept C5 = +template concept C3 = requires(T x) { {g(x)} noexcept; }; \end{codeblock} -The \grammarterm{compound-requirement} in \tcode{C5} +The \grammarterm{compound-requirement} in \tcode{C3} requires that \tcode{g(x)} is a valid expression and that \tcode{g(x)} is non-throwing. \end{example} @@ -2766,8 +2789,6 @@ typename-specifier braced-init-list\br postfix-expression \opt{\terminal{. template}} id-expression\br postfix-expression \opt{\terminal{-> template}} id-expression\br - postfix-expression \terminal{.} pseudo-destructor-name\br - postfix-expression \terminal{->} pseudo-destructor-name\br postfix-expression \terminal{++}\br postfix-expression \terminal{-{-}}\br \terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br @@ -2778,21 +2799,11 @@ \terminal{typeid (} type-id \terminal{)} \end{bnf} - \begin{bnf} \nontermdef{expression-list}\br initializer-list \end{bnf} - -\begin{bnf} -\nontermdef{pseudo-destructor-name}\br - \opt{nested-name-specifier} type-name \terminal{::\,\~} type-name\br - nested-name-specifier \terminal{template} simple-template-id \terminal{::\,\~} type-name\br - \terminal{\~} type-name\br - \terminal{\~} decltype-specifier -\end{bnf} - \pnum \begin{note} The \tcode{>} token following the \grammarterm{type-id} in a \tcode{dynamic_cast}, @@ -2850,8 +2861,7 @@ or it shall have function pointer type. \pnum -For a call to a non-static -member function, +For a call to a non-static member function, the postfix expression shall be an implicit~(\ref{class.mfct.non-static}, \ref{class.static}) or explicit class member access\iref{expr.ref} whose \grammarterm{id-expression} is a @@ -2891,13 +2901,16 @@ \end{note} \pnum -If the \grammarterm{postfix-expression} designates a destructor\iref{class.dtor}, +If the \grammarterm{postfix-expression} names +a destructor or pseudo-destructor\iref{expr.prim.id.dtor}, the type of the function call expression is \tcode{void}; otherwise, the type of the function call expression is the return type of the statically chosen function (i.e., ignoring the \tcode{virtual} keyword), even if the type of the function actually called is different. \indextext{type!incomplete}% This return type shall be an object type, a reference type or \cv{}~\tcode{void}. +If the \grammarterm{postfix-expression} names a pseudo-destructor, +the function call has no effect. \pnum Calling a function through an @@ -3123,35 +3136,6 @@ If the initializer is a parenthesized optional \grammarterm{expression-list}, the specified type shall not be an array type. -\rSec3[expr.pseudo]{Pseudo destructor call} - -\pnum -\indextext{expression!pseudo-destructor call}% -\indextext{call!pseudo destructor}% -\indextext{pseudo-destructor-name}% -The use of a \grammarterm{pseudo-destructor-name} after a dot \tcode{.} or -arrow \tcode{->} operator represents the destructor for the non-class -type denoted by \grammarterm{type-name} or \grammarterm{decltype-specifier}. -The result shall only be used as the -operand for the function call operator \tcode{()}, and the result of -such a call has type \tcode{void}. The only effect is the evaluation of -the \grammarterm{postfix-expression} before the dot or arrow. - -\pnum -The left-hand side of the dot operator shall be of scalar type. The -left-hand side of the arrow operator shall be of pointer to scalar type. -This scalar type is the object type. The cv-unqualified -versions of the object type and of the type designated by the -\grammarterm{pseudo-destructor-name} shall be the same type. Furthermore, -the two \grammarterm{type-name}{s} in a \grammarterm{pseudo-destructor-name} of -the form - -\begin{ncbnf} -\opt{nested-name-specifier} type-name \terminal{::\,\~} type-name -\end{ncbnf} - -shall designate the same scalar type (ignoring cv-qualification). - \rSec3[expr.ref]{Class member access} \pnum @@ -3180,22 +3164,37 @@ \pnum \indextext{type!incomplete}% -For the first option (dot) the first expression -shall be a glvalue having class type. +For the first option (dot) the first expression shall be a glvalue. For the second option (arrow) the first expression -shall be a prvalue having pointer to class type. -In both cases, the class type shall be complete -unless the class member access appears in the definition of that class. -\begin{note} -If the class is incomplete, lookup in the complete class type -is required to refer to the same declaration\iref{basic.scope.class}. -\end{note} +shall be a prvalue having pointer type. The expression \tcode{E1->E2} is converted to the equivalent form \tcode{(*(E1)).E2}; the remainder of \ref{expr.ref}~will address only the first option (dot).\footnote{Note that \tcode{(*(E1))} is an lvalue.} -In either case, the -\grammarterm{id-expression} shall name a member of the class or of one of + +\pnum +Abbreviating +\grammarterm{postfix-expression}\tcode{.}\grammarterm{id-expression} +as \tcode{E1.E2}, \tcode{E1} is called the \defn{object expression}. +If the object expression is of scalar type, +\tcode{E2} shall name the pseudo-destructor +of that same type (ignoring cv-qualifications) and +\tcode{E1.E2} is an lvalue of type ``function of () returning \tcode{void}''. +\begin{note} +This value can only be used +for a notional function call\iref{expr.prim.id.dtor}. +\end{note} + +\pnum +Otherwise, the object expression shall be of class type. +The class type shall be complete +unless the class member access appears in the definition of that class. +\begin{note} +If the class is incomplete, +lookup in the complete class type is required to refer +to the same declaration\iref{basic.scope.class}. +\end{note} +The \grammarterm{id-expression} shall name a member of the class or of one of its base classes. \begin{note} Because the name of a class is inserted in its class scope\iref{class}, @@ -3208,9 +3207,6 @@ \end{note} \pnum -Abbreviating \grammarterm{postfix-expression}\tcode{.}\grammarterm{id-expression} -as \tcode{E1.E2}, -\tcode{E1} is called the \defn{object expression}. If \tcode{E2} is a bit-field, \tcode{E1.E2} is a bit-field. The type and value category of \tcode{E1.E2} are determined as follows. In the remainder of~\ref{expr.ref}, \cvqual{cq} represents either @@ -3591,7 +3587,7 @@ D d; B &br = d; -static_cast(br); // produces lvalue to the original \tcode{d} object +static_cast(br); // produces lvalue denoting the original \tcode{d} object \end{codeblock} \end{example} @@ -3679,15 +3675,14 @@ for specific cases: \pnum -A value of a scoped enumeration type\iref{dcl.enum} can be explicitly converted to an -integral type. When that type is \cv{}~\tcode{bool}, the resulting value is -\tcode{false} if the original value is zero and \tcode{true} for all other -values. For the remaining integral types, the value is unchanged if the -original value can be represented by the -specified type. Otherwise, the resulting value is unspecified. -A value of a scoped enumeration type can also be explicitly converted to a -floating-point type; the result is the same as that of converting from the original -value to the floating-point type. +A value of a scoped enumeration type\iref{dcl.enum} +can be explicitly converted to an integral type; +the result is the same as that of converting +to the enumeration's underlying type and then to the destination type. +A value of a scoped enumeration type +can also be explicitly converted to a floating-point type; +the result is the same as that of converting +from the original value to the floating-point type. \pnum \indextext{enumeration type!conversion to}% @@ -4220,14 +4215,14 @@ performed. The type of the result is the type of the promoted operand. There is an ambiguity in the grammar when \tcode{\~{}} is followed by -a \grammarterm{class-name} or \grammarterm{decltype-specifier}. +a \grammarterm{type-name} or \grammarterm{decltype-specifier}. The ambiguity is resolved by treating \tcode{\~{}} as the unary complement operator rather than as the start of an \grammarterm{unqualified-id} naming a destructor. \begin{note} Because the grammar does not permit an operator to follow the \tcode{.}, \tcode{->}, or \tcode{::} tokens, a \tcode{\~{}} followed by -a \grammarterm{class-name} or \grammarterm{decltype-specifier} in a +a \grammarterm{type-name} or \grammarterm{decltype-specifier} in a member access expression or \grammarterm{qualified-id} is unambiguously parsed as a destructor name. \end{note} @@ -4281,8 +4276,9 @@ has function or incomplete type, to the parenthesized name of such types, or to a glvalue that designates a bit-field. -\tcode{sizeof(char)}, \tcode{sizeof(signed char)} and -\tcode{sizeof(unsigned char)} are \tcode{1}. The result of +The result of \tcode{sizeof} +applied to any of the narrow character types is \tcode{1}. +The result of \tcode{sizeof} applied to any other fundamental type\iref{basic.fundamental} is \impldef{\tcode{sizeof} applied to fundamental types @@ -5570,26 +5566,24 @@ left operand. \indextext{left shift!undefined}% The behavior is undefined if the right operand is negative, or greater -than or equal to the length in bits of the promoted left operand. +than or equal to the range exponent of the promoted left operand. \pnum -The value of \tcode{E1 << E2} is \tcode{E1} left-shifted \tcode{E2} bit positions; vacated bits are -zero-filled. If \tcode{E1} has an unsigned type, the value of the result -is $\mathrm{E1}\times2^\mathrm{E2}$, reduced modulo -one more than the maximum value representable in the result type. Otherwise, if -\tcode{E1} has a signed type and non-negative value, and $\mathrm{E1}\times2^\mathrm{E2}$ is -representable in the corresponding unsigned type of the result type, then -that value, converted to the result type, is the resulting value; otherwise, the -behavior is undefined. +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. +\begin{note} +\tcode{E1} is left-shifted \tcode{E2} bit positions; +vacated bits are zero-filled. +\end{note} \pnum -The value of \tcode{E1 >> E2} is \tcode{E1} right-shifted \tcode{E2} -bit positions. If \tcode{E1} has an unsigned type or if \tcode{E1} has a -signed type and a non-negative value, the value of the result is the -integral part of the quotient of $\mathrm{E1}/2^\mathrm{E2}$. If \tcode{E1} -\indextext{right shift!implementation-defined}% -has a signed type and a negative value, the resulting value is -\impldef{result of right shift of negative value}. +The value of \tcode{E1 >> E2} is $\tcode{E1} / 2^\tcode{E2}$, rounded down. +\begin{note} +\tcode{E1} is right-shifted \tcode{E2} bit positions. +Right-shift on signed integral types is an arithmetic right shift, +which performs sign-extension. +\end{note} \pnum The expression \tcode{E1} is sequenced before the expression \tcode{E2}. @@ -5793,7 +5787,7 @@ or enumeration type. If both operands are pointers, pointer conversions\iref{conv.ptr} and qualification conversions\iref{conv.qual} are performed to bring -them to their composite pointer type\iref{expr.prop}. +them to their composite pointer type\iref{expr.type}. After conversions, the operands shall have the same type. \pnum @@ -5873,7 +5867,7 @@ pointer conversions\iref{conv.ptr}, function pointer conversions\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} -are performed on both operands to bring them to their composite pointer type\iref{expr.prop}. +are performed on both operands to bring them to their composite pointer type\iref{expr.type}. Comparing pointers is defined as follows: \begin{itemize} @@ -5896,7 +5890,7 @@ 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 -their composite pointer type\iref{expr.prop}. +their composite pointer type\iref{expr.type}. Comparing pointers to members is defined as follows: \begin{itemize} @@ -5988,9 +5982,17 @@ \end{bnf} \pnum -The usual arithmetic conversions\iref{expr.arith.conv} are performed; the result is the -bitwise \logop{AND} function of the operands. The operator -applies only to integral or unscoped enumeration operands. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if both $\tcode{x}_i$ and $\tcode{y}_i$ are 1, and 0 otherwise. +\begin{note} +The result is the bitwise \logop{AND} function of the operands. +\end{note} \rSec2[expr.xor]{Bitwise exclusive OR operator}% \indextext{expression!bitwise exclusive OR}% @@ -6004,9 +6006,18 @@ \end{bnf} \pnum -The usual arithmetic conversions\iref{expr.arith.conv} are performed; the result is the -bitwise exclusive \logop{OR} function of the operands. The -operator applies only to integral or unscoped enumeration operands. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if either (but not both) of $\tcode{x}_i$ and $\tcode{y}_i$ are 1, +and 0 otherwise. +\begin{note} +The result is the bitwise exclusive \logop{OR} function of the operands. +\end{note} \rSec2[expr.or]{Bitwise inclusive OR operator}% \indextext{expression!bitwise inclusive OR}% @@ -6020,9 +6031,17 @@ \end{bnf} \pnum -The usual arithmetic conversions\iref{expr.arith.conv} are performed; the result is the -bitwise inclusive \logop{OR} function of its operands. The -operator applies only to integral or unscoped enumeration operands. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if at least one of $\tcode{x}_i$ and $\tcode{y}_i$ are 1, and 0 otherwise. +\begin{note} +The result is the bitwise inclusive \logop{OR} function of the operands. +\end{note} \rSec2[expr.log.and]{Logical AND operator}% \indextext{expression!logical AND}% @@ -6235,13 +6254,13 @@ function pointer conversions\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} are performed to bring them to their -composite pointer type\iref{expr.prop}. The result is of the composite +composite pointer type\iref{expr.type}. The result is of the composite pointer type. \item One or both of the second and third operands have pointer-to-member type; pointer to member conversions\iref{conv.mem} and qualification conversions\iref{conv.qual} are performed to bring them to their composite -pointer type\iref{expr.prop}. The result is of the composite pointer type. +pointer type\iref{expr.type}. The result is of the composite pointer type. \item Both the second and third operands have type \tcode{std::nullptr_t} or one has @@ -6488,6 +6507,34 @@ conditional-expression \end{bnf} +\pnum +A \defn{constant initializer} for a variable or temporary object \tcode{o} is +an initializer for which interpreting its full-expression +as a \grammarterm{constant-expression} results in a constant expression, +except that if \tcode{o} is an object, +such an initializer may also invoke constexpr constructors +for \tcode{o} and its subobjects +even if those objects are of non-literal class types. +\begin{note} +Such a class may have a non-trivial destructor. +Within this evaluation, +\tcode{std::is_constant_evaluated()}\iref{meta.const.eval} +returns \tcode{true}. +\end{note} + +\pnum +A variable is +\defn{usable in constant expressions} after +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} unless the evaluation of \tcode{e}, following the rules of the abstract @@ -6536,20 +6583,8 @@ \begin{itemize} \item - a non-volatile glvalue of integral or enumeration type that refers - to a complete non-volatile const object with a preceding initialization, - initialized with a constant expression, or - - \item - a non-volatile glvalue that refers to a subobject of a string - literal\iref{lex.string}, or - - \item - a non-volatile glvalue that refers to a non-volatile object - defined with \tcode{constexpr} or - a template parameter object\iref{temp.param}, - or that refers to a non-mutable subobject - of such an object, or + a non-volatile glvalue that refers to an object that is + usable in constant expressions, or \item a non-volatile glvalue of literal type that refers to a non-volatile object @@ -6567,11 +6602,6 @@ for a union whose active member (if any) is mutable, unless the lifetime of the union object began within the evaluation of \tcode{e}; -\item -an assignment expression\iref{expr.ass} -or invocation of an assignment operator\iref{class.copy.assign} -that would change the active member of a union; - \item an \grammarterm{id-expression} that refers to a variable or data member of reference type @@ -6579,7 +6609,7 @@ \begin{itemize} \item - it is initialized with a constant expression or + it is usable in constant expressions or \item its lifetime began within the evaluation of \tcode{e}; @@ -6629,14 +6659,11 @@ \item a conversion from type \cv{}~\tcode{void*} to a pointer-to-object type; -\item -a dynamic cast\iref{expr.dynamic.cast}; - \item a \tcode{reinterpret_cast}\iref{expr.reinterpret.cast}; \item -a pseudo-destructor call\iref{expr.pseudo}; +a pseudo-destructor call\iref{expr.prim.id.dtor}; \item modification of an object~(\ref{expr.ass}, \ref{expr.post.incr}, @@ -6645,10 +6672,6 @@ that refers to a non-volatile object whose lifetime began within the evaluation of \tcode{e}; -\item -a typeid expression\iref{expr.typeid} whose operand is a glvalue of a -polymorphic class type; - \item a \grammarterm{new-expression}\iref{expr.new}; @@ -6665,7 +6688,9 @@ operator where the result is unspecified; \item -a \grammarterm{throw-expression}\iref{expr.throw}; or +a \grammarterm{throw-expression}\iref{expr.throw} or +a dynamic cast\iref{expr.dynamic.cast} or \tcode{typeid}\iref{expr.typeid} expression +that would throw an exception; or \item an invocation of the \tcode{va_arg} macro\iref{cstdarg.syn}. @@ -6802,8 +6827,12 @@ if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object\iref{expr.add}, - the address of a function, - or a null pointer value, and + the address of a non-immediate function, + or a null pointer value, + + \item + if the value is of pointer-to-member-function type, + it does not designate an immediate function, and \item if the value is an object of class or array type, @@ -6813,8 +6842,18 @@ \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 it is a -function. +a temporary object whose value satisfies the above constraints, or +it is a non-immediate function. +\begin{example} +\begin{codeblock} +consteval int f() { return 42; } +consteval auto g() { return f; } +consteval int h(int (*p)() = g()) { return p(); } +constexpr int r = h(); // OK +constexpr auto e = g(); // ill-formed: a pointer to an immediate function is + // not a permitted result of a constant expression +\end{codeblock} +\end{example} \pnum \begin{note} Since this document @@ -6835,19 +6874,67 @@ It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}. \end{example} \end{note}% +\pnum +An expression or conversion is in an \defn{immediate function context} +if it is potentially evaluated and +its innermost non-block scope is +a function parameter scope of an immediate function. +An expression or conversion is an \defn{immediate invocation} +if it is an explicit or implicit invocation of an immediate function and +is not in an immediate function context. +An immediate invocation shall be a constant expression. +\begin{note} +An immediate invocation is evaluated even in an unevaluated operand. +\end{note} + +\pnum +An expression or conversion \tcode{e} is \defn{manifestly constant-evaluated} +if it is: +\begin{itemize} +\item a \grammarterm{constant-expression}, or +\item the condition of a constexpr if statement\iref{stmt.if}, or +\item an immediate invocation, or +\item a \grammarterm{constraint-expression}\iref{temp.constr.decl} +including one formed from the \grammarterm{constraint-logical-or-expression} +of a \grammarterm{requires-clause}, or +\item the initializer of a variable +that is usable in constant expressions or +has constant initialization.\footnote{Testing this condition +may involve a trial evaluation of its initializer as described above.} +\begin{example} +\begin{codeblock} +template struct X {}; +X x; // type \tcode{X} +int y; +const int a = std::is_constant_evaluated() ? y : 1; // dynamic initialization to 1 +double z[a]; // ill-formed: \tcode{a} is not usable + // in constant expressions +const int b = std::is_constant_evaluated() ? 2 : y; // static initialization to 2 +int c = y + (std::is_constant_evaluated() ? 2 : y); // dynamic initialization to \tcode{y+y} + +constexpr int f() { + const int n = std::is_constant_evaluated() ? 13 : 17; // \tcode{n} is 13 + int m = std::is_constant_evaluated() ? 13 : 17; // \tcode{m} might be 13 or 17 (see below) + char arr[n] = {}; // char[13] + return m + sizeof(arr); +} +int p = f(); // \tcode{m} is 13; initialized to 26 +int q = p + f(); // \tcode{m} is 17 for this call; initialized to 56 +\end{codeblock} +\end{example} +\end{itemize} + \pnum \indextext{expression!potentially constant evaluated}% -An expression is \defn{potentially constant evaluated} +An expression or conversion is \defn{potentially constant evaluated} if it is: \begin{itemize} \item -a potentially-evaluated expression\iref{basic.def.odr}, +a manifestly constant-evaluated expression, \item -a \grammarterm{constraint-expression}, -including one formed from the \grammarterm{constraint-logical-or-expression} -of a \grammarterm{requires-clause}, +a potentially-evaluated expression\iref{basic.def.odr}, \item an immediate subexpression of a \grammarterm{braced-init-list},% @@ -6881,4 +6968,21 @@ is of non-volatile const-qualified integral type or of reference type. \end{itemize} +\begin{example} +\begin{codeblock} +struct N { + constexpr N() {} + N(N const&) = delete; +}; +template constexpr void bad_assert_copyable() { T t; T t2 = t; } +using ineffective = decltype(bad_assert_copyable()); + // \tcode{bad_assert_copyable} is not needed for constant evaluation + // (and thus not instantiated) +template consteval void assert_copyable() { T t; T t2 = t; } +using check = decltype(assert_copyable()); + // error: \tcode{assert_copyable} is instantiated (because it is needed for constant + // evaluation), but the attempt to copy \tcode{t} is ill-formed +\end{codeblock} +\end{example} + \indextext{expression|)} diff --git a/source/future.tex b/source/future.tex index 48744a49e9..1fb805188a 100644 --- a/source/future.tex +++ b/source/future.tex @@ -1382,7 +1382,7 @@ \begin{itemdescr} \pnum \returns -\tcode{\&sb}. +\tcode{const_cast(\&sb)}. \end{itemdescr} \indexlibrarymember{freeze}{strstream}% @@ -2309,3 +2309,97 @@ \pnum \effects The destructor shall delete \tcode{cvtptr}. \end{itemdescr} + +\rSec1[depr.locale.category]{Deprecated locale category facets} + +\pnum +The \tcode{ctype} locale category includes the following facets +as if they were specified +in table \tref{localization.category.facets} of \ref{locale.category}. + +\begin{codeblock} +codecvt +codecvt +\end{codeblock} + +\pnum +The \tcode{ctype} locale category includes the following facets +as if they were specified +in table \tref{localization.required.specializations} of \ref{locale.category}. + +\begin{codeblock} +codecvt_byname +codecvt_byname +\end{codeblock} + +\pnum +The following class template specializations are required +in addition to those specified in~\ref{locale.codecvt}. +The specialization \tcode{codecvt} +converts between the UTF-16 and UTF-8 encoding forms, and +the specialization \tcode{codecvt} +converts between the UTF-32 and UTF-8 encoding forms. + +\rSec1[depr.fs.path.factory]{Deprecated filesystem path factory functions} + +\indexlibrary{\idxcode{u8path}}% +\begin{itemdecl} +template + path u8path(const Source& source); +template + path u8path(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The \tcode{source} and \range{first}{last} + sequences are UTF-8 encoded. The value type of \tcode{Source} + and \tcode{InputIterator} is \tcode{char}. + \tcode{Source} meets the requirements specified in \ref{fs.path.req}. + +\pnum +\returns +\begin{itemize} +\item If \tcode{value_type} is \tcode{char} and the current native + narrow encoding\iref{fs.path.type.cvt} is UTF-8, + return \tcode{path(source)} or \tcode{path(first, last)}; + otherwise, +\item if \tcode{value_type} is \tcode{wchar_t} and the + native wide encoding is UTF-16, or + if \tcode{value_type} is \tcode{char16_t} or \tcode{char32_t}, + convert \tcode{source} or \range{first}{last} + to a temporary, \tcode{tmp}, of type \tcode{string_type} and + return \tcode{path(tmp)}; + otherwise, +\item convert \tcode{source} or \range{first}{last} + to a temporary, \tcode{tmp}, of type \tcode{u32string} and + return \tcode{path(tmp)}. +\end{itemize} + +\pnum +\remarks Argument format conversion\iref{fs.path.fmt.cvt} applies to the + arguments for these functions. How Unicode encoding conversions are performed is + unspecified. + +\pnum +\begin{example} +A string is to be read from a database that is encoded in UTF-8, and used + to create a directory using the native encoding for filenames: +\begin{codeblock} +namespace fs = std::filesystem; +std::string utf8_string = read_utf8_data(); +fs::create_directory(fs::u8path(utf8_string)); +\end{codeblock} + +For POSIX-based operating systems with the native narrow encoding set + to UTF-8, no encoding or type conversion occurs. + +For POSIX-based operating systems with the native narrow encoding not + set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the + current native narrow encoding. Some Unicode characters may have no native character + set representation. + +For Windows-based operating systems a conversion from UTF-8 to + UTF-16 occurs. +\end{example} +\end{itemdescr} diff --git a/source/grammar.tex b/source/grammar.tex index 02135b574f..a4da2357d2 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -25,7 +25,8 @@ \begin{ncbnf} typedef-name:\br - identifier + identifier\br + simple-template-id \end{ncbnf} \begin{ncbnf} @@ -53,9 +54,4 @@ identifier \end{ncbnf} -Note that a -\grammarterm{typedef-name} -naming a class is also a -\grammarterm{class-name}\iref{class.name}. - \FlushAndPrintGrammar diff --git a/source/iostreams.tex b/source/iostreams.tex index 08761d5f78..ae814c4881 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -162,13 +162,19 @@ \indexlibrary{\idxcode{wsyncbuf}}% \indexlibrary{\idxcode{osyncstream}}% \indexlibrary{\idxcode{wosyncstream}}% +\indexlibrary{\idxcode{fpos}}% +\indexlibrary{\idxcode{streampos}}% +\indexlibrary{\idxcode{wstreampos}}% +\indexlibrary{\idxcode{u16streampos}}% +\indexlibrary{\idxcode{u32streampos}}% \begin{codeblock} namespace std { - template class char_traits; - template<> class char_traits; - template<> class char_traits; - template<> class char_traits; - template<> class char_traits; + template struct char_traits; + template<> struct char_traits; + template<> struct char_traits; + template<> struct char_traits; + template<> struct char_traits; + template<> struct char_traits; template class allocator; @@ -259,6 +265,9 @@ template class fpos; using streampos = fpos::state_type>; using wstreampos = fpos::state_type>; + using u8streampos = fpos::state_type>; + using u16streampos = fpos::state_type>; + using u32streampos = fpos::state_type>; } \end{codeblock} @@ -301,9 +310,10 @@ class template specialization \tcode{basic_streambuf} serves as a base class for class templates -\tcode{basic_stringbuf} +\tcode{basic_stringbuf}, +\tcode{basic_filebuf}, and -\tcode{basic_filebuf}. +\tcode{basic_syncbuf}. \pnum The @@ -319,9 +329,10 @@ class template specialization \tcode{basic_ostream} serves as a base class for class templates -\tcode{basic_ostringstream} +\tcode{basic_ostringstream}, +\tcode{basic_ofstream}, and -\tcode{basic_ofstream}. +\tcode{basic_osyncstream}. \pnum The @@ -332,6 +343,15 @@ and \tcode{basic_fstream}. +\pnum +\begin{note} +For each of the class templates above, +the program is ill-formed if +\tcode{traits::char_type} +is not the same type as +\tcode{charT}\iref{char.traits}. +\end{note} + \pnum Other \grammarterm{typedef-name}{s} define instances of class templates @@ -346,8 +366,7 @@ \tcode{fpos} are used for specifying file position information. - -\pnum +\begin{example} The types \tcode{streampos} and @@ -357,6 +376,7 @@ and \tcode{wchar_t} respectively. +\end{example} \pnum \begin{note} @@ -366,17 +386,6 @@ \tcode{char_traits}. An implementation can avoid this circularity by substituting equivalent types. -One way to do this might be -\begin{codeblock} -template class fpos { @\commentellip@ }; // depends on nothing -using _STATE = @\commentellip@ ; // implementation private declaration of \tcode{stateT} - -using streampos = fpos<_STATE>; - -template<> struct char_traits { - using pos_type = streampos; -} -\end{codeblock} \end{note} \rSec1[iostream.objects]{Standard iostream objects} @@ -739,7 +748,7 @@ public: class failure; // see below - // \ref{ios::fmtflags}, \tcode{fmtflags} + // \ref{ios.fmtflags}, \tcode{fmtflags} using fmtflags = @\textit{T1}@; static constexpr fmtflags boolalpha = @\unspec@; static constexpr fmtflags dec = @\unspec@; @@ -760,14 +769,14 @@ static constexpr fmtflags basefield = @\seebelow@; static constexpr fmtflags floatfield = @\seebelow@; - // \ref{ios::iostate}, \tcode{iostate} + // \ref{ios.iostate}, \tcode{iostate} using iostate = @\textit{T2}@; static constexpr iostate badbit = @\unspec@; static constexpr iostate eofbit = @\unspec@; static constexpr iostate failbit = @\unspec@; static constexpr iostate goodbit = @\seebelow@; - // \ref{ios::openmode}, \tcode{openmode} + // \ref{ios.openmode}, \tcode{openmode} using openmode = @\textit{T3}@; static constexpr openmode app = @\unspec@; static constexpr openmode ate = @\unspec@; @@ -776,7 +785,7 @@ static constexpr openmode out = @\unspec@; static constexpr openmode trunc = @\unspec@; - // \ref{ios::seekdir}, \tcode{seekdir} + // \ref{ios.seekdir}, \tcode{seekdir} using seekdir = @\textit{T4}@; static constexpr seekdir beg = @\unspec@; static constexpr seekdir cur = @\unspec@; @@ -880,7 +889,7 @@ \rSec3[ios.types]{Types} -\rSec4[ios::failure]{Class \tcode{ios_base::failure}} +\rSec4[ios.failure]{Class \tcode{ios_base::failure}} \indexlibrary{\idxcode{ios_base::failure}}% \indexlibrary{\idxcode{ios_base}!\idxcode{failure}}% @@ -943,7 +952,7 @@ \tcode{failure} by constructing the base class with \tcode{msg} and \tcode{ec}. \end{itemdescr} -\rSec4[ios::fmtflags]{Type \tcode{ios_base::fmtflags}} +\rSec4[ios.fmtflags]{Type \tcode{ios_base::fmtflags}} \indexlibrarymember{fmtflags}{ios_base}% \begin{itemdecl} @@ -1006,7 +1015,7 @@ \end{floattable} \end{itemdescr} -\rSec4[ios::iostate]{Type \tcode{ios_base::iostate}} +\rSec4[ios.iostate]{Type \tcode{ios_base::iostate}} \indexlibrarymember{iostate}{ios_base}% \begin{itemdecl} @@ -1042,7 +1051,7 @@ \end{itemize} \end{itemdescr} -\rSec4[ios::openmode]{Type \tcode{ios_base::openmode}} +\rSec4[ios.openmode]{Type \tcode{ios_base::openmode}} \indexlibrarymember{openmode}{ios_base}% \begin{itemdecl} @@ -1072,7 +1081,7 @@ \end{libefftab} \end{itemdescr} -\rSec4[ios::seekdir]{Type \tcode{ios_base::seekdir}} +\rSec4[ios.seekdir]{Type \tcode{ios_base::seekdir}} \indexlibrarymember{seekdir}{ios_base}% \begin{itemdecl} @@ -1096,7 +1105,7 @@ \end{libefftabmean} \end{itemdescr} -\rSec4[ios::Init]{Class \tcode{ios_base::Init}} +\rSec4[ios.init]{Class \tcode{ios_base::Init}} \indexlibrary{\idxcode{ios_base::Init}}% \indexlibrary{\idxcode{ios_base}!\idxcode{Init}}% @@ -1171,7 +1180,7 @@ \tcode{wclog.flush()}. \end{itemdescr} -\rSec3[fmtflags.state]{\tcode{ios_base} state functions} +\rSec3[fmtflags.state]{State functions} \indexlibrarymember{flags}{ios_base}% \begin{itemdecl} @@ -1191,7 +1200,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{fmtfl == flags()}. \pnum @@ -1269,7 +1278,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{prec == precision()}. \pnum @@ -1297,7 +1306,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{wide == width()}. \pnum @@ -1306,7 +1315,7 @@ \tcode{width()}. \end{itemdescr} -\rSec3[ios.base.locales]{\tcode{ios_base} functions} +\rSec3[ios.base.locales]{Functions} \indexlibrarymember{imbue}{ios_base}% \begin{itemdecl} @@ -1333,7 +1342,7 @@ \tcode{getloc()}. \pnum -\postconditions +\ensures \tcode{loc == getloc()}. \end{itemdescr} @@ -1352,7 +1361,7 @@ perform locale-dependent input and output operations. \end{itemdescr} -\rSec3[ios.members.static]{\tcode{ios_base} static members} +\rSec3[ios.members.static]{Static members} \indexlibrarymember{sync_with_stdio}{ios_base}% \begin{itemdecl} @@ -1413,7 +1422,7 @@ } \end{itemdescr} -\rSec3[ios.base.storage]{\tcode{ios_base} storage functions} +\rSec3[ios.base.storage]{Storage functions} \indexlibrarymember{xalloc}{ios_base}% \begin{itemdecl} @@ -1536,7 +1545,7 @@ for the same object, the earlier return value may no longer be valid. \end{itemdescr} -\rSec3[ios.base.callback]{\tcode{ios_base} callbacks} +\rSec3[ios.base.callback]{Callbacks} \indexlibrarymember{register_callback}{ios_base}% \begin{itemdecl} @@ -1573,7 +1582,7 @@ A function registered twice will be called twice. \end{itemdescr} -\rSec3[ios.base.cons]{\tcode{ios_base} constructors/destructor} +\rSec3[ios.base.cons]{Constructors and destructor} \indexlibrary{\idxcode{ios_base}!constructor}% \begin{itemdecl} @@ -1628,7 +1637,7 @@ } \end{codeblock} -\rSec3[fpos.members]{\tcode{fpos} members} +\rSec3[fpos.members]{Members} \indexlibrarymember{state}{fpos}% \begin{itemdecl} @@ -1652,7 +1661,7 @@ Current value of \tcode{st}. \end{itemdescr} -\rSec3[fpos.operations]{\tcode{fpos} requirements} +\rSec3[fpos.operations]{Requirements} \pnum \indexlibrary{\idxcode{fpos}}% @@ -1711,7 +1720,7 @@ & & \effects Value-initializes the state object. \br - \postconditions \tcode{p == P(o)} \\ \rowsep + \ensures \tcode{p == P(o)} \\ \rowsep \tcode{P()} & \tcode{P} & \tcode{P(0)} & @@ -1837,7 +1846,7 @@ } \end{codeblock} -\rSec3[basic.ios.cons]{\tcode{basic_ios} constructors} +\rSec3[basic.ios.cons]{Constructors} \indexlibrary{\idxcode{basic_ios}!constructor}% \begin{itemdecl} @@ -1889,7 +1898,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures The postconditions of this function are indicated in \tref{iostreams.basicios.init.effects}. \begin{libefftabvalue}{\tcode{basic_ios::init()} effects}{tab:iostreams.basicios.init.effects} @@ -1946,7 +1955,7 @@ \tcode{tiestr->tie()}. \pnum -\postconditions +\ensures \tcode{tiestr == tie()}. \pnum @@ -1975,7 +1984,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{sb == rdbuf()}. \pnum @@ -2052,7 +2061,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{traits::eq(fillch, fill())}. \pnum @@ -2070,7 +2079,7 @@ \pnum \effects If -\tcode{(this == \&rhs)} +\tcode{(this == addressof(rhs))} does nothing. Otherwise assigns to the member objects of \tcode{*this} @@ -2112,7 +2121,7 @@ \end{note} \pnum -\postconditions +\ensures The postconditions of this function are indicated in \tref{iostreams.copyfmt.effects}. @@ -2151,7 +2160,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{*this} shall have the state that +\ensures \tcode{*this} shall have the state that \tcode{rhs} had before the function call, except that \tcode{rdbuf()} shall return 0. \tcode{rhs} shall be in a valid but unspecified state, except that \tcode{rhs.rdbuf()} shall return the @@ -2187,13 +2196,13 @@ \tcode{clear()}. \pnum -\postconditions \tcode{rdbuf() == sb}. +\ensures \tcode{rdbuf() == sb}. \pnum \throws Nothing. \end{itemdescr} -\rSec3[iostate.flags]{\tcode{basic_ios} flags functions} +\rSec3[iostate.flags]{Flags functions} \indexlibrarymember{operator bool}{basic_ios}% \begin{itemdecl} @@ -2234,7 +2243,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures If \tcode{rdbuf() != 0} then @@ -2247,7 +2256,7 @@ If \tcode{((state | (rdbuf() ? goodbit : badbit)) \& exceptions()) == 0}, returns. Otherwise, the function throws an object of class -\tcode{basic_ios::failure}\iref{ios::failure}, +\tcode{basic_ios::failure}\iref{ios.failure}, constructed with \impldef{argument values to construct \tcode{basic_ios::failure}} argument values.% @@ -2264,7 +2273,7 @@ Calls \tcode{clear(rdstate() | state)} (which may throw -\tcode{basic_ios::failure}\iref{ios::failure}). +\tcode{basic_ios::failure}\iref{ios.failure}). \end{itemdescr} \indexlibrarymember{good}{basic_ios}% @@ -2349,7 +2358,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{except == exceptions()}. \pnum @@ -3052,7 +3061,7 @@ \term{output sequence}. \end{itemize} -\rSec3[streambuf.cons]{\tcode{basic_streambuf} constructors} +\rSec3[streambuf.cons]{Constructors} \indexlibrary{\idxcode{basic_streambuf}!constructor}% \begin{itemdecl} @@ -3100,7 +3109,7 @@ \effects Constructs a copy of \tcode{rhs}. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{eback() == rhs.eback()} @@ -3124,7 +3133,7 @@ None. \end{itemdescr} -\rSec3[streambuf.members]{\tcode{basic_streambuf} public member functions} +\rSec3[streambuf.members]{Public member functions} \rSec4[streambuf.locales]{Locales} @@ -3135,7 +3144,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{loc == getloc()}. \pnum @@ -3367,7 +3376,7 @@ \tcode{xsputn(s, n)}. \end{itemdescr} -\rSec3[streambuf.protected]{\tcode{basic_streambuf} protected member functions} +\rSec3[streambuf.protected]{Protected member functions} \rSec4[streambuf.assign]{Assignment} @@ -3382,7 +3391,7 @@ to \tcode{*this}. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{eback() == rhs.eback()} @@ -3462,7 +3471,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{gbeg == eback()}, \tcode{gnext == gptr()}, and @@ -3522,14 +3531,14 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{pbeg == pbase()}, \tcode{pbeg == pptr()}, and \tcode{pend == epptr()}. \end{itemdescr} -\rSec3[streambuf.virtuals]{\tcode{basic_streambuf} virtual functions} +\rSec3[streambuf.virtuals]{Virtual functions} \rSec4[streambuf.virt.locales]{Locales} @@ -3906,7 +3915,7 @@ \end{itemize} \pnum -\postconditions +\ensures On return, the constraints of \tcode{gptr()}, \tcode{eback()}, @@ -4197,7 +4206,7 @@ explicit basic_istream(basic_streambuf* sb); virtual ~basic_istream(); - // \ref{istream::sentry}, prefix/suffix + // \ref{istream.sentry}, prefix/suffix class sentry; // \ref{istream.formatted}, formatted input @@ -4268,12 +4277,12 @@ template basic_istream& operator>>(basic_istream&, signed char&); - template - basic_istream& operator>>(basic_istream&, charT*); - template - basic_istream& operator>>(basic_istream&, unsigned char*); - template - basic_istream& operator>>(basic_istream&, signed char*); + template + basic_istream& operator>>(basic_istream&, charT(&)[N]); + template + basic_istream& operator>>(basic_istream&, unsigned char(&)[N]); + template + basic_istream& operator>>(basic_istream&, signed char(&)[N]); } \end{codeblock} @@ -4329,7 +4338,7 @@ it does not throw anything and proceeds as if the called function had returned a failure indication. -\rSec4[istream.cons]{\tcode{basic_istream} constructors} +\rSec4[istream.cons]{Constructors} \indexlibrary{\idxcode{basic_istream}!constructor}% \begin{itemdecl} @@ -4345,7 +4354,7 @@ \tcode{basic_ios::init(sb)}\iref{basic.ios.cons}. \pnum -\postconditions +\ensures \tcode{gcount() == 0}. \end{itemdescr} @@ -4381,7 +4390,7 @@ \tcode{rdbuf()}. \end{itemdescr} -\rSec4[istream.assign]{Class \tcode{basic_istream} assign and swap} +\rSec4[istream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_istream}% \begin{itemdecl} @@ -4408,7 +4417,7 @@ \tcode{rhs.gcount()}. \end{itemdescr} -\rSec4[istream::sentry]{Class \tcode{basic_istream::sentry}} +\rSec4[istream.sentry]{Class \tcode{basic_istream::sentry}} \indexlibrary{\idxcode{basic_istream::sentry}}% \indexlibrary{\idxcode{sentry}!\idxcode{basic_istream}}% @@ -4754,12 +4763,12 @@ \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} -template - basic_istream& operator>>(basic_istream& in, charT* s); -template - basic_istream& operator>>(basic_istream& in, unsigned char* s); -template - basic_istream& operator>>(basic_istream& in, signed char* s); +template + basic_istream& operator>>(basic_istream& in, charT (&s)[N]); +template + basic_istream& operator>>(basic_istream& in, unsigned char (&s)[N]); +template + basic_istream& operator>>(basic_istream& in, signed char (&s)[N]); \end{itemdecl} \begin{itemdescr} @@ -4772,17 +4781,12 @@ object is constructed, \tcode{operator>>} extracts characters and stores them into -successive locations of an array whose first element is designated by \tcode{s}. If \tcode{width()} is greater than zero, \tcode{n} is -\tcode{width()}. -Otherwise \tcode{n} is the number of elements -of the largest array of -\tcode{char_type} -that can store a terminating -\tcode{charT()}. +\tcode{min(size_t(width()), N)}. +Otherwise \tcode{n} is \tcode{N}. \tcode{n} is the maximum number of characters stored. \pnum @@ -5583,7 +5587,7 @@ constructing a sentry object extracts characters as long as the next available character \tcode{c} is whitespace or until there are no more characters in the sequence. Whitespace characters are distinguished with the same criterion as used by -\tcode{sentry::sentry}\iref{istream::sentry}. +\tcode{sentry::sentry}\iref{istream.sentry}. If \tcode{ws} stops extracting characters because there are no more available it sets @@ -5658,7 +5662,7 @@ inherits a number of functions that allow reading input and writing output to sequences controlled by a stream buffer. -\rSec4[iostream.cons]{\tcode{basic_iostream} constructors} +\rSec4[iostream.cons]{Constructors} \indexlibrary{\idxcode{basic_iostream}!constructor}% \begin{itemdecl} @@ -5675,7 +5679,7 @@ \tcode{basic_ostream(sb)}\iref{ostream}. \pnum -\postconditions +\ensures \tcode{rdbuf() == sb} and \tcode{gcount() == 0}. @@ -5693,7 +5697,7 @@ \tcode{move(rhs)}. \end{itemdescr} -\rSec4[iostream.dest]{\tcode{basic_iostream} destructor} +\rSec4[iostream.dest]{Destructor} \indexlibrary{\idxcode{basic_iostream}!destructor}% \begin{itemdecl} @@ -5712,7 +5716,7 @@ \tcode{rdbuf()}. \end{itemdescr} -\rSec4[iostream.assign]{\tcode{basic_iostream} assign and swap} +\rSec4[iostream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_iostream}% \begin{itemdecl} @@ -5763,7 +5767,7 @@ explicit basic_ostream(basic_streambuf* sb); virtual ~basic_ostream(); - // \ref{ostream::sentry}, prefix/suffix + // \ref{ostream.sentry}, prefix/suffix class sentry; // \ref{ostream.formatted}, formatted output @@ -5884,7 +5888,7 @@ rethrows the exception without completing its actions, otherwise it does not throw anything and treat as an error. -\rSec4[ostream.cons]{\tcode{basic_ostream} constructors} +\rSec4[ostream.cons]{Constructors} \indexlibrary{\idxcode{basic_ostream}!constructor}% \begin{itemdecl} @@ -5900,7 +5904,7 @@ \tcode{basic_ios::init(sb)}\iref{basic.ios.cons}. \pnum -\postconditions +\ensures \tcode{rdbuf() == sb}. \end{itemdescr} @@ -5934,7 +5938,7 @@ \tcode{rdbuf()}. \end{itemdescr} -\rSec4[ostream.assign]{Class \tcode{basic_ostream} assign and swap} +\rSec4[ostream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_ostream}% \begin{itemdecl} @@ -5959,7 +5963,7 @@ \effects Calls \tcode{basic_ios::swap(rhs)}. \end{itemdescr} -\rSec4[ostream::sentry]{Class \tcode{basic_ostream::sentry}} +\rSec4[ostream.sentry]{Class \tcode{basic_ostream::sentry}} \indexlibrary{\idxcode{basic_ostream::sentry}}% \indexlibrary{\idxcode{sentry}!\idxcode{basic_ostream}}% @@ -6052,7 +6056,7 @@ \tcode{ok_}. \end{itemdescr} -\rSec4[ostream.seeks]{\tcode{basic_ostream} seek members} +\rSec4[ostream.seeks]{Seek members} \pnum Each seek member function begins execution by constructing an object of class \tcode{sentry}. @@ -6639,7 +6643,7 @@ \tcode{*this}. \end{itemdescr} -\rSec3[ostream.manip]{Standard \tcode{basic_ostream} manipulators} +\rSec3[ostream.manip]{Standard manipulators} \pnum Each instantiation of any of the function templates @@ -7267,7 +7271,7 @@ \tcode{in >> quoted(s, delim, escape)} behaves as if it extracts the following characters from \tcode{in} using \tcode{operator>>(basic_istream\&, charT\&)}\iref{istream.extractors} -which may throw \tcode{ios_base::failure}\iref{ios::failure}: +which may throw \tcode{ios_base::failure}\iref{ios.failure}: \begin{itemize} \item If the first character extracted is equal to \tcode{delim}, as determined by \tcode{traits_type::eq}, then: @@ -7437,7 +7441,7 @@ set if the output sequence can be written. \end{itemize} -\rSec3[stringbuf.cons]{\tcode{basic_stringbuf} constructors} +\rSec3[stringbuf.cons]{Constructors} \indexlibrary{\idxcode{basic_stringbuf}!constructor}% \begin{itemdecl} @@ -7453,9 +7457,15 @@ \tcode{basic_streambuf()}\iref{streambuf.cons}, and initializing \tcode{mode} with \tcode{which}. +It is +\impldef{whether sequence pointers are initialized to null pointers} +whether the sequence pointers +(\tcode{eback()}, \tcode{gptr()}, \tcode{egptr()}, +\tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}) +are initialized to null pointers. \pnum -\postconditions +\ensures \tcode{str() == ""}. \end{itemdescr} @@ -7497,7 +7507,7 @@ also copied. \pnum -\postconditions Let \tcode{rhs_p} refer to the state of +\ensures Let \tcode{rhs_p} refer to the state of \tcode{rhs} just prior to this construction and let \tcode{rhs_a} refer to the state of \tcode{rhs} just after this construction. @@ -7516,7 +7526,7 @@ \end{itemize} \end{itemdescr} -\rSec3[stringbuf.assign]{Assign and swap} +\rSec3[stringbuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_stringbuf}% \begin{itemdecl} @@ -7597,7 +7607,7 @@ sequence and initializes the input and output sequences according to \tcode{mode}. \pnum -\postconditions If \tcode{mode \& ios_base::out} is nonzero, \tcode{pbase()} points to the +\ensures If \tcode{mode \& ios_base::out} is nonzero, \tcode{pbase()} points to the first underlying character and \tcode{epptr()} \tcode{>= pbase() + s.size()} holds; in addition, if \tcode{mode \& ios_base::ate} is nonzero, \tcode{pptr() == pbase() + s.size()} @@ -7934,7 +7944,7 @@ \tcode{sb}, the \tcode{stringbuf} object. \end{itemize} -\rSec3[istringstream.cons]{\tcode{basic_istringstream} constructors} +\rSec3[istringstream.cons]{Constructors} \indexlibrary{\idxcode{basic_istringstream}!constructor}% \begin{itemdecl} @@ -7947,9 +7957,9 @@ Constructs an object of class \tcode{basic_istringstream}, initializing the base class with -\tcode{basic_istream(\&sb)}\iref{istream} -and initializing \tcode{sb} with -\tcode{basic_string\-buf(which | ios_base::in)}\iref{stringbuf.cons}. +\tcode{basic_istream(addressof(sb))}\iref{istream} +and initializing \tcode{sb} with\linebreak % avoid Overfull +\tcode{basic_stringbuf(which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_istringstream}!constructor}% @@ -7965,9 +7975,9 @@ Constructs an object of class \tcode{basic_istringstream}, initializing the base class with -\tcode{basic_istream(\&sb)}\iref{istream} -and initializing \tcode{sb} with -\tcode{basic_string\-buf(str, which | ios_base::in)}\iref{stringbuf.cons}. +\tcode{basic_istream(addressof(sb))}\iref{istream} +and initializing \tcode{sb} with\linebreak % avoid Overfull +\tcode{basic_stringbuf(str, which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_istringstream}!constructor}% @@ -7980,11 +7990,12 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Next \tcode{basic_istream::set_rdbuf(\&sb)} is called to +Next \tcode{basic_istream::set_rdbuf(addressof(sb))} +is called to install the contained \tcode{basic_stringbuf}. \end{itemdescr} -\rSec3[istringstream.assign]{Assign and swap} +\rSec3[istringstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_istringstream}% \begin{itemdecl} @@ -8036,7 +8047,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)}. +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% @@ -8121,7 +8132,7 @@ \tcode{sb}, the \tcode{stringbuf} object. \end{itemize} -\rSec3[ostringstream.cons]{\tcode{basic_ostringstream} constructors} +\rSec3[ostringstream.cons]{Constructors} \indexlibrary{\idxcode{basic_ostringstream}!constructor}% \begin{itemdecl} @@ -8134,9 +8145,9 @@ Constructs an object of class \tcode{basic_ostringstream}, initializing the base class with -\tcode{basic_ostream(\&sb)}\iref{ostream} -and initializing \tcode{sb} with -\tcode{basic_string\-buf(which | ios_base::out)}\iref{stringbuf.cons}. +\tcode{basic_ostream(addressof(sb))}\iref{ostream} +and initializing \tcode{sb} with\linebreak % avoid Overfull +\tcode{basic_stringbuf(which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ostringstream}!constructor}% @@ -8152,9 +8163,9 @@ Constructs an object of class \tcode{basic_ostringstream}, initializing the base class with -\tcode{basic_ostream(\&sb)}\iref{ostream} -and initializing \tcode{sb} with -\tcode{basic_string\-buf(str, which | ios_base::out)}\iref{stringbuf.cons}. +\tcode{basic_ostream(addressof(sb))}\iref{ostream} +and initializing \tcode{sb} with\linebreak % avoid Overfull +\tcode{basic_stringbuf(str, which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ostringstream}!constructor}% @@ -8167,11 +8178,12 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Next \tcode{basic_ostream::set_rdbuf(\&sb)} is called to +Next \tcode{basic_ostream::set_rdbuf(addressof(sb))} +is called to install the contained \tcode{basic_stringbuf}. \end{itemdescr} -\rSec3[ostringstream.assign]{Assign and swap} +\rSec3[ostringstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_ostringstream}% \begin{itemdecl} @@ -8223,7 +8235,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)}. +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% @@ -8309,7 +8321,7 @@ \tcode{sb}, the \tcode{stringbuf} object. \end{itemize} -\rSec3[stringstream.cons]{\tcode{basic_stringstream} constructors} +\rSec3[stringstream.cons]{Constructors} \indexlibrary{\idxcode{basic_stringstream}!constructor}% \begin{itemdecl} @@ -8322,7 +8334,7 @@ Constructs an object of class \tcode{basic_stringstream}, initializing the base class with -\tcode{basic_iostream(\&sb)}\iref{iostream.cons} +\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} and initializing \tcode{sb} with @@ -8342,7 +8354,7 @@ Constructs an object of class \tcode{basic_stringstream}, initializing the base class with -\tcode{basic_iostream(\&sb)}\iref{iostream.cons} +\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} and initializing \tcode{sb} with @@ -8359,11 +8371,11 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. -Next \tcode{basic_istream::set_rdbuf(\&sb)} is called to +Next \tcode{basic_istream::set_rdbuf(addressof(sb))} is called to install the contained \tcode{basic_stringbuf}. \end{itemdescr} -\rSec3[stringstream.assign]{Assign and swap} +\rSec3[stringstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_stringstream}% \begin{itemdecl} @@ -8415,7 +8427,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)} +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% @@ -8614,7 +8626,7 @@ use_facet>(getloc()); \end{codeblock} -\rSec3[filebuf.cons]{\tcode{basic_filebuf} constructors} +\rSec3[filebuf.cons]{Constructors} \indexlibrary{\idxcode{basic_filebuf}!constructor}% \begin{itemdecl} @@ -8630,7 +8642,7 @@ \tcode{basic_streambuf()}\iref{streambuf.cons}. \pnum -\postconditions +\ensures \tcode{is_open() == false}. \end{itemdescr} @@ -8655,7 +8667,7 @@ copied. \pnum -\postconditions Let \tcode{rhs_p} refer to the state of +\ensures Let \tcode{rhs_p} refer to the state of \tcode{rhs} just prior to this construction and let \tcode{rhs_a} refer to the state of \tcode{rhs} just after this construction. @@ -8690,7 +8702,7 @@ If an exception occurs during the destruction of the object, including the call to \tcode{close()}, the exception is caught but not rethrown (see~\ref{res.on.exception.handling}). \end{itemdescr} -\rSec3[filebuf.assign]{Assign and swap} +\rSec3[filebuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_filebuf}% \begin{itemdecl} @@ -8755,6 +8767,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{s} shall point to a NTCTS\iref{defns.ntcts}. + \pnum \effects If @@ -8764,13 +8780,11 @@ initializes the \tcode{filebuf} as required. -It then opens a file, if possible, whose name is the -\ntbs{} \tcode{s} -(as if by calling -\tcode{fopen(s, modstr)}). -\indextext{NTBS}% +It then opens +the file to which \tcode{s} resolves, if possible, +as if by a call to \tcode{fopen} \indexlibrary{\idxcode{fopen}}% -The \ntbs{} \tcode{modstr} is determined from +with the second argument determined from \tcode{mode \& \~{}ios_base::ate} as indicated in \tref{iostreams.file.open.modes}. If \tcode{mode} is not some combination of flags shown in the table then @@ -8805,9 +8819,9 @@ If the open operation succeeds and \tcode{(mode \& ios_base::ate) != 0}, positions the file to the end -(as if by calling -\tcode{fseek(file, 0, SEEK_END)}).\footnote{The macro -\tcode{SEEK_END} +(as if by calling \tcode{fseek(file, 0, SEEK_END)}, where +\tcode{file} is the pointer returned by calling \tcode{fopen}).% +\footnote{The macro \tcode{SEEK_END} is defined, and the function signatures \indexlibrary{\idxcode{fopen}}% \tcode{fopen(const char*, const char*)} @@ -8886,7 +8900,7 @@ on success, a null pointer otherwise. \pnum -\postconditions +\ensures \tcode{is_open() == false}. \end{itemdescr} @@ -9342,7 +9356,7 @@ \tcode{sb}, the \tcode{filebuf} object. \end{itemize} -\rSec3[ifstream.cons]{\tcode{basic_ifstream} constructors} +\rSec3[ifstream.cons]{Constructors} \indexlibrary{\idxcode{basic_ifstream}!constructor}% \begin{itemdecl} @@ -9355,7 +9369,7 @@ Constructs an object of class \tcode{basic_ifstream}, initializing the base class with -\tcode{basic_istream(\&sb)}\iref{istream.cons} +\tcode{basic_istream(addressof(sb))}\iref{istream.cons} and initializing \tcode{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} @@ -9374,7 +9388,7 @@ Constructs an object of class \tcode{basic_ifstream}, initializing the base class with -\tcode{basic_istream(\&sb)}\iref{istream.cons} +\tcode{basic_istream(addressof(sb))}\iref{istream.cons} and initializing \tcode{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls @@ -9406,11 +9420,12 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_filebuf}. Next -\tcode{basic_istream::set_rdbuf(\&sb)} is called to install +\tcode{basic_istream::set_rdbuf(\brk{}addressof(sb))} +is called to install the contained \tcode{basic_filebuf}. \end{itemdescr} -\rSec3[ifstream.assign]{Assign and swap} +\rSec3[ifstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_ifstream}% \begin{itemdecl} @@ -9461,7 +9476,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)}. +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{is_open}{basic_ifstream}% @@ -9590,7 +9605,7 @@ \tcode{sb}, the \tcode{filebuf} object. \end{itemize} -\rSec3[ofstream.cons]{\tcode{basic_ofstream} constructors} +\rSec3[ofstream.cons]{Constructors} \indexlibrary{\idxcode{basic_ofstream}!constructor}% \begin{itemdecl} @@ -9603,7 +9618,7 @@ Constructs an object of class \tcode{basic_ofstream}, initializing the base class with -\tcode{basic_ostream(\&sb)}\iref{ostream.cons} +\tcode{basic_ostream(addressof(sb))}\iref{ostream.cons} and initializing \tcode{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} @@ -9622,7 +9637,7 @@ Constructs an object of class \tcode{basic_ofstream}, initializing the base class with -\tcode{basic_ostream(\&sb)}\iref{ostream.cons} +\tcode{basic_ostream(addressof(sb))}\iref{ostream.cons} and initializing \tcode{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls @@ -9654,11 +9669,12 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_filebuf}. Next -\tcode{basic_ostream::set_rdbuf(\&sb)} is called to install +\tcode{basic_ostream::set_rdbuf(\brk{}addressof(sb))} +is called to install the contained \tcode{basic_filebuf}. \end{itemdescr} -\rSec3[ofstream.assign]{Assign and swap} +\rSec3[ofstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_ofstream}% \begin{itemdecl} @@ -9709,7 +9725,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)}. +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{is_open}{basic_ofstream}% @@ -9847,7 +9863,7 @@ \tcode{sb}, the \tcode{basic_filebuf} object. \end{itemize} -\rSec3[fstream.cons]{\tcode{basic_fstream} constructors} +\rSec3[fstream.cons]{Constructors} \indexlibrary{\idxcode{basic_fstream}!constructor}% \begin{itemdecl} @@ -9860,7 +9876,7 @@ Constructs an object of class \tcode{basic_fstream}, initializing the base class with -\tcode{basic_iostream(\&sb)}\iref{iostream.cons} +\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} and initializing \tcode{sb} with @@ -9883,7 +9899,7 @@ Constructs an object of class \tcode{basic_fstream}, initializing the base class with -\tcode{basic_iostream(\&sb)}\iref{iostream.cons} +\tcode{basic_iostream(addressof(sb))}\iref{iostream.cons} and initializing \tcode{sb} with @@ -9919,11 +9935,12 @@ \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_filebuf}. Next -\tcode{basic_istream::set_rdbuf(\&sb)} is called to install +\tcode{basic_istream::set_rdbuf(\brk{}addressof(sb))} +is called to install the contained \tcode{basic_filebuf}. \end{itemdescr} -\rSec3[fstream.assign]{Assign and swap} +\rSec3[fstream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_fstream}% \begin{itemdecl} @@ -9974,7 +9991,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(\&sb)}. +\tcode{const_cast*>(addressof(sb))}. \end{itemdescr} \indexlibrarymember{is_open}{basic_fstream}% @@ -10164,7 +10181,7 @@ by memory allocation. \pnum -\postconditions +\ensures \tcode{get_wrapped() == obuf} and \tcode{get_allocator() == allocator} are \tcode{true}. \end{itemdescr} @@ -10180,7 +10197,7 @@ Move constructs from \tcode{other} (\tref{moveconstructible}). \pnum -\postconditions +\ensures The value returned by \tcode{this->get_wrapped()} is the value returned by \tcode{other.get_wrapped()} prior to calling this constructor. @@ -10237,7 +10254,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{rhs.get_wrapped() == nullptr} is \tcode{true}. @@ -10305,7 +10322,7 @@ \end{itemize} \pnum -\postconditions +\ensures On success, the associated output is empty. \pnum @@ -10432,7 +10449,7 @@ // \ref{syncstream.osyncstream.members}, member functions void emit(); streambuf_type* get_wrapped() const noexcept; - syncbuf_type* rdbuf() const noexcept { return &sb ; } + syncbuf_type* rdbuf() const noexcept { return const_cast(addressof(sb)); } private: syncbuf_type sb; // \expos @@ -10478,7 +10495,7 @@ \pnum \effects Initializes \tcode{sb} from \tcode{buf} and \tcode{allocator}. -Initializes the base class with \tcode{basic_ostream(\&sb)}. +Initializes the base class with \tcode{basic_ostream(addressof(sb))}. \pnum \begin{note} @@ -10488,7 +10505,7 @@ \end{note} \pnum -\postconditions +\ensures \tcode{get_wrapped() == buf} is \tcode{true}. \end{itemdescr} @@ -10502,10 +10519,10 @@ \effects Move constructs the base class and \tcode{sb} from the corresponding subobjects of \tcode{other}, -and calls \tcode{basic_ostream::set_rdbuf(\&sb)}. +and calls \tcode{basic_ostream::set_rdbuf(addressof(sb))}. \pnum -\postconditions +\ensures The value returned by \tcode{get_wrapped()} is the value returned by \tcode{os.get_wrapped()} prior to calling this constructor. @@ -10546,7 +10563,7 @@ \end{note} \pnum -\postconditions +\ensures \tcode{nullptr == rhs.get_wrapped()} is \tcode{true}. \tcode{get_wrapped()} returns the value previously returned by \tcode{rhs.get_wrapped()}. @@ -10696,8 +10713,8 @@ \pnum Implementations should provide such behavior as it is defined by -POSIX. Implementations shall document any behavior that differs from the -behavior defined by POSIX. Implementations that do not support exact POSIX +POSIX\@. Implementations shall document any behavior that differs from the +behavior defined by POSIX\@. Implementations that do not support exact POSIX behavior should provide behavior as close to POSIX behavior as is reasonable given the limitations of actual operating systems and file systems. If an implementation cannot provide any reasonable behavior, the implementation shall report an error as specified in~\ref{fs.err.report}. @@ -10752,7 +10769,7 @@ \pnum This subclause mentions commercially available operating systems for purposes of exposition.\footnote{ -POSIX\textregistered\ is a registered trademark of The IEEE. +POSIX\textregistered\ is a registered trademark of The IEEE\@. Windows\textregistered\ is a registered trademark of Microsoft Corporation. This information is given for the convenience of users of this document and does not constitute an endorsement by ISO or IEC of these @@ -10762,7 +10779,7 @@ \rSec2[fs.req]{Requirements} \pnum -Throughout this subclause, \tcode{char}, \tcode{wchar_t}, +Throughout this subclause, \tcode{char}, \tcode{wchar_t}, \tcode{char8_t}, \tcode{char16_t}, and \tcode{char32_t} are collectively called \defnx{encoded character types}{encoded character type}. @@ -10805,21 +10822,6 @@ void swap(path& lhs, path& rhs) noexcept; size_t hash_value(const path& p) noexcept; - bool operator==(const path& lhs, const path& rhs) noexcept; - bool operator!=(const path& lhs, const path& rhs) noexcept; - bool operator< (const path& lhs, const path& rhs) noexcept; - bool operator<=(const path& lhs, const path& rhs) noexcept; - bool operator> (const path& lhs, const path& rhs) noexcept; - bool operator>=(const path& lhs, const path& rhs) noexcept; - - path operator/ (const path& lhs, const path& rhs); - - // \ref{fs.path.factory}, \tcode{path} factory functions - template - path u8path(const Source& source); - template - path u8path(InputIterator first, InputIterator last); - // \ref{fs.class.filesystem_error}, filesystem errors class filesystem_error; @@ -11194,6 +11196,16 @@ path& replace_extension(const path& replacement = path()); void swap(path& rhs) noexcept; + // \ref{fs.path.nonmember}, non-member operators + friend bool operator==(const path& lhs, const path& rhs) noexcept; + friend bool operator!=(const path& lhs, const path& rhs) noexcept; + friend bool operator< (const path& lhs, const path& rhs) noexcept; + friend bool operator<=(const path& lhs, const path& rhs) noexcept; + friend bool operator> (const path& lhs, const path& rhs) noexcept; + friend bool operator>=(const path& lhs, const path& rhs) noexcept; + + friend path operator/ (const path& lhs, const path& rhs); + // \ref{fs.path.native.obs}, native format observers const string_type& native() const noexcept; const value_type* c_str() const noexcept; @@ -11205,7 +11217,7 @@ string(const Allocator& a = Allocator()) const; std::string string() const; std::wstring wstring() const; - std::string u8string() const; + std::u8string u8string() const; std::u16string u16string() const; std::u32string u32string() const; @@ -11216,7 +11228,7 @@ generic_string(const Allocator& a = Allocator()) const; std::string generic_string() const; std::wstring generic_wstring() const; - std::string generic_u8string() const; + std::u8string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const; @@ -11426,9 +11438,9 @@ which is said to be \term{normalized}. \indextext{path!normalization|)}% -\rSec3[fs.path.cvt]{\tcode{path} conversions} +\rSec3[fs.path.cvt]{Conversions} -\rSec4[fs.path.fmt.cvt]{\tcode{path} argument format conversions} +\rSec4[fs.path.fmt.cvt]{Argument format conversions} \pnum \begin{note} @@ -11504,10 +11516,10 @@ \end{note} -\rSec4[fs.path.type.cvt]{\tcode{path} type and encoding conversions} +\rSec4[fs.path.type.cvt]{Type and encoding conversions} \pnum -The \defn{native encoding} of a narrow character string is +The \defn{native encoding} of an ordinary character string is the operating system dependent current encoding for pathnames\iref{fs.class.path}. The \defn{native encoding} for wide character strings is @@ -11523,18 +11535,18 @@ to be converted to is determined by its value type: \begin{itemize} -\item \tcode{char}: The encoding is the native narrow encoding. +\item \tcode{char}: The encoding is the native ordinary encoding. The method of conversion, if any, is operating system dependent. \begin{note} For POSIX-based operating systems \tcode{path::value_type} is \tcode{char} so no conversion from \tcode{char} value type arguments or to \tcode{char} value type return values is performed. For Windows-based operating systems, the -native narrow encoding is determined by calling a Windows API function. +native ordinary encoding is determined by calling a Windows API function. \end{note} \begin{note} This results in behavior identical to other C and \Cpp{} -standard library functions that perform file operations using narrow character +standard library functions that perform file operations using ordinary character strings to identify paths. Changing this behavior would be surprising and error prone. \end{note} @@ -11545,6 +11557,8 @@ so no conversion from \tcode{wchar_t} value type arguments or to \tcode{wchar_t} value type return values is performed. \end{note} +\item \tcode{char8_t}: The encoding is UTF-8. The method of conversion +is unspecified. \item \tcode{char16_t}: The encoding is UTF-16. The method of conversion is unspecified. \item \tcode{char32_t}: The encoding is UTF-32. The method of conversion @@ -11557,7 +11571,7 @@ Implementations should not modify member function arguments if already of type \tcode{path::value_type}. -\rSec3[fs.path.req]{\tcode{path} requirements} +\rSec3[fs.path.req]{Requirements} \pnum In addition to the requirements\iref{fs.req}, @@ -11570,14 +11584,14 @@ \item \tcode{basic_string_view}. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source.begin()}{source.end()}. -\item A type meeting the \oldconcept{InputIterator} requirements that iterates over a NTCTS. +\item A type meeting the \oldconcept{InputIterator} requirements that iterates over a NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to \tcode{iterator_traits::value_type()}. \item A character array that after array-to-pointer decay results in a - pointer to the start of a NTCTS. The value type shall be an encoded character type. A + pointer to the start of a NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to @@ -11607,9 +11621,9 @@ Arguments of type \tcode{Source} shall not be null pointers. -\rSec3[fs.path.member]{\tcode{path} members} +\rSec3[fs.path.member]{Members} -\rSec4[fs.path.construct]{\tcode{path} constructors} +\rSec4[fs.path.construct]{Constructors} \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} @@ -11621,7 +11635,7 @@ \effects Constructs an object of class \tcode{path}. \pnum -\postconditions \tcode{empty() == true}. +\ensures \tcode{empty() == true}. \end{itemdescr} \indexlibrary{\idxcode{path}!constructor}% @@ -11698,7 +11712,7 @@ \item Otherwise a conversion is performed using the \tcode{codecvt} facet of \tcode{loc}, and then a second -conversion to the current narrow encoding. +conversion to the current ordinary encoding. \end{itemize} \pnum @@ -11720,12 +11734,12 @@ \tcode{latin1_facet} to convert ISO/IEC 8859-1 encoded \tcode{latin1_string} to a wide character string in the native wide encoding\iref{fs.path.type.cvt}. The resulting wide string is then -converted to a narrow character -pathname string in the current native narrow encoding. If the -native wide encoding is UTF-16 or UTF-32, and the current native narrow +converted to an ordinary character +pathname string in the current native ordinary encoding. If the +native wide encoding is UTF-16 or UTF-32, and the current native ordinary encoding is UTF-8, all of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation, but for other native -narrow encodings some characters may have no representation. +ordinary encodings some characters may have no representation. For Windows-based operating systems, the path is constructed by using \tcode{latin1_facet} to convert ISO/IEC 8859-1 encoded @@ -11735,7 +11749,7 @@ \end{example} \end{itemdescr} -\rSec4[fs.path.assign]{\tcode{path} assignments} +\rSec4[fs.path.assign]{Assignments} \indexlibrarymember{operator=}{path}% \begin{itemdecl} @@ -11812,7 +11826,7 @@ \returns \tcode{*this}. \end{itemdescr} -\rSec4[fs.path.append]{\tcode{path} appends} +\rSec4[fs.path.append]{Appends} \pnum The append operations use \tcode{operator/=} to denote their semantic effect of appending @@ -11895,7 +11909,7 @@ \effects Equivalent to: \tcode{return operator/=(path(first, last));} \end{itemdescr} -\rSec4[fs.path.concat]{\tcode{path} concatenation} +\rSec4[fs.path.concat]{Concatenation} \indexlibrarymember{operator+=}{path}% \indexlibrarymember{concat}{path}% @@ -11936,7 +11950,7 @@ \effects Equivalent to: \tcode{return *this += path(first, last);} \end{itemdescr} -\rSec4[fs.path.modifiers]{\tcode{path} modifiers} +\rSec4[fs.path.modifiers]{Modifiers} \indexlibrarymember{clear}{path}% \begin{itemdecl} @@ -11945,7 +11959,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{empty() == true}. +\ensures \tcode{empty() == true}. \end{itemdescr} \indexlibrarymember{make_preferred}{path}% @@ -11992,7 +12006,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{!has_filename()}. +\ensures \tcode{!has_filename()}. \pnum \effects Remove the generic format pathname of \tcode{filename()} from the generic format pathname. @@ -12072,7 +12086,7 @@ \complexity Constant time. \end{itemdescr} -\rSec4[fs.path.native.obs]{\tcode{path} native format observers} +\rSec4[fs.path.native.obs]{Native format observers} \pnum The string returned by all native format observers is in the native pathname format\iref{fs.class.path}. @@ -12138,7 +12152,7 @@ \begin{itemdecl} std::string string() const; std::wstring wstring() const; -std::string u8string() const; +std::u8string u8string() const; std::u16string u16string() const; std::u32string u32string() const; \end{itemdecl} @@ -12150,11 +12164,10 @@ \pnum \remarks Conversion, if any, is performed as specified by \ref{fs.path.cvt}. -The encoding of the string returned by \tcode{u8string()} is always UTF-8. \end{itemdescr} -\rSec4[fs.path.generic.obs]{\tcode{path} generic format observers} +\rSec4[fs.path.generic.obs]{Generic format observers} \pnum Generic format observer functions return strings formatted according to the @@ -12196,7 +12209,7 @@ \begin{itemdecl} std::string generic_string() const; std::wstring generic_wstring() const; -std::string generic_u8string() const; +std::u8string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const; \end{itemdecl} @@ -12207,11 +12220,9 @@ \pnum \remarks Conversion, if any, is specified by~\ref{fs.path.cvt}. -The encoding of the string returned by \tcode{generic_u8string()} is always -UTF-8. \end{itemdescr} -\rSec4[fs.path.compare]{\tcode{path} compare} +\rSec4[fs.path.compare]{Compare} \indexlibrarymember{compare}{path}% \begin{itemdecl} @@ -12221,45 +12232,50 @@ \begin{itemdescr} \pnum \returns - \begin{itemize} -\item A value less than \tcode{0}, - if \tcode{native()} for the elements of \tcode{*this} - are lexicographically less than \tcode{native()} for the elements of \tcode{p}; - otherwise, -\item a value greater than \tcode{0}, - if \tcode{native()} for the elements of \tcode{*this} - are lexicographically greater than \tcode{native()} for the elements of \tcode{p}; - otherwise, -\item \tcode{0}. - \end{itemize} - -\pnum -\remarks The elements are determined as if by iteration over the half-open -range \range{begin()}{end()} for \tcode{*this} and \tcode{p}. +\begin{itemize} +\item + Let \tcode{rootNameComparison} be the result of + \tcode{this->root_name().native().compare(p.root_name().native())}. + If \tcode{rootNameComparison} is not \tcode{0}, + \tcode{rootNameComparison}. +\item + Otherwise, if + \tcode{!this->has_root_directory()} and \tcode{p.has_root_directory()}, + a value less than \tcode{0}. +\item + Otherwise, if + \tcode{this->has_root_directory()} and \tcode{!p.has_root_directory()}, + a value greater than \tcode{0}. +\item + Otherwise, if + \tcode{native()} for the elements of \tcode{this->relative_path()} + are lexicographically less than + \tcode{native()} for the elements of \tcode{p.relative_path()}, + a value less than \tcode{0}. +\item + Otherwise, if + \tcode{native()} for the elements of \tcode{this->relative_path()} + are lexicographically greater than + \tcode{native()} for the elements of \tcode{p.relative_path()}, + a value greater than \tcode{0}. +\item + Otherwise, \tcode{0}. +\end{itemize} \end{itemdescr} \indexlibrarymember{compare}{path}% \begin{itemdecl} int compare(const string_type& s) const int compare(basic_string_view s) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{compare(path(s))}. -\end{itemdescr} - -\indexlibrarymember{compare}{path}% -\begin{itemdecl} int compare(const value_type* s) const \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{compare(path(s))}. +\effects Equivalent to: \tcode{return compare(path(s));} \end{itemdescr} -\rSec4[fs.path.decompose]{\tcode{path} decomposition} +\rSec4[fs.path.decompose]{Decomposition} \indexlibrarymember{root_name}{path}% \begin{itemdecl} @@ -12404,7 +12420,7 @@ \end{note} \end{itemdescr} -\rSec4[fs.path.query]{\tcode{path} query} +\rSec4[fs.path.query]{Query} \indexlibrarymember{empty}{path}% \begin{itemdecl} @@ -12522,7 +12538,7 @@ \returns \tcode{!is_absolute()}. \end{itemdescr} -\rSec4[fs.path.gen]{\tcode{path} generation} +\rSec4[fs.path.gen]{Generation} \indexlibrarymember{lexically_normal}{path}% \begin{itemdecl} @@ -12573,9 +12589,13 @@ Then, \begin{itemize} \item if \tcode{a == end()} and \tcode{b == base.end()}, returns \tcode{path(".")}; otherwise -\item let \tcode{n} be the number of \grammarterm{filename} elements in \range{b}{base.end()} -that are not dot or dot-dot minus the number that are dot-dot. +\item + let \tcode{n} be the number of \grammarterm{filename} elements in \range{b}{base.end()} + that are not dot or dot-dot or empty, minus the number that are dot-dot. If \tcode{n<0,} returns \tcode{path()}; otherwise +\item + if \tcode{n == 0} and \tcode{(a == end() || a->empty())}, + returns \tcode{path(".")}; otherwise \item returns an object of class \tcode{path} that is default-constructed, followed by \begin{itemize} \item application of \tcode{operator/=(path(".."))} @@ -12633,7 +12653,7 @@ \tcode{*this}, \tcode{base}, or both. \end{note} \end{itemdescr} -\rSec3[fs.path.itr]{\tcode{path} iterators} +\rSec3[fs.path.itr]{Iterators} \indexlibrary{\idxcode{path}!\idxcode{iterator}}% \pnum @@ -12693,7 +12713,7 @@ \returns The end iterator. \end{itemdescr} -\rSec3[fs.path.io]{\tcode{path} inserter and extractor} +\rSec3[fs.path.io]{Inserter and extractor} \indexlibrarymember{operator<<}{path}% \begin{itemdecl} @@ -12732,7 +12752,7 @@ \returns \tcode{is}. \end{itemdescr} -\rSec3[fs.path.nonmember]{\tcode{path} non-member functions} +\rSec3[fs.path.nonmember]{Non-member functions} \indexlibrary{\idxcode{swap}!\idxcode{path}}% \begin{itemdecl} @@ -12757,7 +12777,7 @@ \indexlibrarymember{operator==}{path}% \begin{itemdecl} -bool operator==(const path& lhs, const path& rhs) noexcept; +friend bool operator==(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12784,7 +12804,7 @@ \indexlibrarymember{operator"!=}{path}% \begin{itemdecl} -bool operator!=(const path& lhs, const path& rhs) noexcept; +friend bool operator!=(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12794,7 +12814,7 @@ \indexlibrarymember{operator<}{path}% \begin{itemdecl} -bool operator< (const path& lhs, const path& rhs) noexcept; +friend bool operator< (const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12804,7 +12824,7 @@ \indexlibrarymember{operator<=}{path}% \begin{itemdecl} -bool operator<=(const path& lhs, const path& rhs) noexcept; +friend bool operator<=(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12814,7 +12834,7 @@ \indexlibrarymember{operator>}{path}% \begin{itemdecl} -bool operator> (const path& lhs, const path& rhs) noexcept; +friend bool operator> (const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12824,7 +12844,7 @@ \indexlibrarymember{operator>=}{path}% \begin{itemdecl} -bool operator>=(const path& lhs, const path& rhs) noexcept; +friend bool operator>=(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -12834,7 +12854,7 @@ \indexlibrarymember{operator/}{path}% \begin{itemdecl} -path operator/ (const path& lhs, const path& rhs); +friend path operator/ (const path& lhs, const path& rhs); \end{itemdecl} \begin{itemdescr} @@ -12842,70 +12862,6 @@ \effects Equivalent to: \tcode{return path(lhs) /= rhs;} \end{itemdescr} -\rSec4[fs.path.factory]{\tcode{path} factory functions} - -\indexlibrary{\idxcode{u8path}}% -\begin{itemdecl} -template - path u8path(const Source& source); -template - path u8path(InputIterator first, InputIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires The \tcode{source} and \range{first}{last} - sequences are UTF-8 encoded. The value type of \tcode{Source} - and \tcode{InputIterator} is \tcode{char}. - -\pnum -\returns -\begin{itemize} -\item If \tcode{value_type} is \tcode{char} and the current native - narrow encoding\iref{fs.path.type.cvt} is UTF-8, - return \tcode{path(source)} or \tcode{path(first, last)}; - otherwise, -\item if \tcode{value_type} is \tcode{wchar_t} and the - native wide encoding is UTF-16, or - if \tcode{value_type} is \tcode{char16_t} or \tcode{char32_t}, - convert \tcode{source} or \range{first}{last} - to a temporary, \tcode{tmp}, of type \tcode{string_type} and - return \tcode{path(tmp)}; - otherwise, -\item convert \tcode{source} or \range{first}{last} - to a temporary, \tcode{tmp}, of type \tcode{u32string} and - return \tcode{path(tmp)}. -\end{itemize} - -\pnum -\remarks Argument format conversion\iref{fs.path.fmt.cvt} applies to the - arguments for these functions. How Unicode encoding conversions are performed is - unspecified. - -\pnum -\begin{example} -A string is to be read from a database that is encoded in UTF-8, and used - to create a directory using the native encoding for filenames: -\begin{codeblock} -namespace fs = std::filesystem; -std::string utf8_string = read_utf8_data(); -fs::create_directory(fs::u8path(utf8_string)); -\end{codeblock} - -For POSIX-based operating systems with the native narrow encoding set - to UTF-8, no encoding or type conversion occurs. - -For POSIX-based operating systems with the native narrow encoding not - set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the - current native narrow encoding. Some Unicode characters may have no native character - set representation. - -For Windows-based operating systems a conversion from UTF-8 to - UTF-16 occurs. -\end{example} -\end{itemdescr} - - \rSec2[fs.class.filesystem_error]{Class \tcode{filesystem_error}} \indexlibrary{\idxcode{filesystem_error}}% @@ -12930,7 +12886,7 @@ objects thrown as exceptions to report file system errors from functions described in this subclause. -\rSec3[fs.filesystem_error.members]{\tcode{filesystem_error} members} +\rSec3[fs.filesystem_error.members]{Members} \pnum Constructors are provided that store zero, one, or two paths associated with @@ -12943,7 +12899,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{code() == ec}, \item \tcode{path1().empty() == true}, @@ -12959,7 +12915,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{code() == ec}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, @@ -12975,7 +12931,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{code() == ec}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, @@ -13226,10 +13182,10 @@ \tcode{permissions} shall replace the file's permission bits with \tcode{perm} \\ \rowsep \tcode{add} & \tcode{permissions} shall replace the file's permission bits with - the bitwise OR of \tcode{perm} and the file's current permission bits. \\ \rowsep + the bitwise \logop{OR} of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{remove} & \tcode{permissions} shall replace the file's permission bits with - the bitwise AND of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep + the bitwise \logop{AND} of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{nofollow} & \tcode{permissions} shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. \\ @@ -13294,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]{\tcode{file_status} constructors} +\rSec3[fs.file_status.cons]{Constructors} \indexlibrary{\idxcode{file_status}!constructor}% \begin{itemdecl} @@ -13303,10 +13259,10 @@ \begin{itemdescr} \pnum -\postconditions \tcode{type() == ft} and \tcode{permissions() == prms}. +\ensures \tcode{type() == ft} and \tcode{permissions() == prms}. \end{itemdescr} -\rSec3[fs.file_status.obs]{\tcode{file_status} observers} +\rSec3[fs.file_status.obs]{Observers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -13330,7 +13286,7 @@ \tcode{operator=}, or \tcode{permissions(perms)} function. \end{itemdescr} -\rSec3[fs.file_status.mods]{\tcode{file_status} modifiers} +\rSec3[fs.file_status.mods]{Modifiers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -13339,7 +13295,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{type() == ft}. +\ensures \tcode{type() == ft}. \end{itemdescr} \indexlibrarymember{permissions}{file_status}% @@ -13349,7 +13305,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{permissions() == prms}. +\ensures \tcode{permissions() == prms}. \end{itemdescr} \rSec2[fs.class.directory_entry]{Class \tcode{directory_entry}} @@ -13480,7 +13436,7 @@ regardless of whether or not it employs caching. \end{example} -\rSec3[fs.dir.entry.cons]{\tcode{directory_entry} constructors} +\rSec3[fs.dir.entry.cons]{Constructors} \indexlibrary{\idxcode{directory_entry}!constructor}% \begin{itemdecl} @@ -13494,14 +13450,14 @@ then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. \pnum -\postconditions \tcode{path() == p} if no error occurs, +\ensures \tcode{path() == p} if no error occurs, otherwise \tcode{path() == filesystem::path()}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} -\rSec3[fs.dir.entry.mods]{\tcode{directory_entry} modifiers} +\rSec3[fs.dir.entry.mods]{Modifiers} \indexlibrarymember{assign}{directory_entry}% \begin{itemdecl} @@ -13558,7 +13514,7 @@ \end{note} \end{itemdescr} -\rSec3[fs.dir.entry.obs]{\tcode{directory_entry} observers} +\rSec3[fs.dir.entry.obs]{Observers} \pnum Unqualified function names in the \returns elements of the @@ -13945,7 +13901,7 @@ POSIX \tcode{readdir_r}. \end{note} -\rSec3[fs.dir.itr.members]{\tcode{directory_iterator} members} +\rSec3[fs.dir.itr.members]{Members} \indexlibrary{\idxcode{directory_iterator}!constructor}% \begin{itemdecl} @@ -13996,7 +13952,7 @@ \effects Constructs an object of class \tcode{directory_iterator}. \pnum -\postconditions \tcode{*this} has the original value of \tcode{rhs}. +\ensures \tcode{*this} has the original value of \tcode{rhs}. \end{itemdescr} \indexlibrarymember{operator=}{directory_iterator}% @@ -14011,7 +13967,7 @@ object, the member has no effect. \pnum -\postconditions \tcode{*this} has the original value of \tcode{rhs}. +\ensures \tcode{*this} has the original value of \tcode{rhs}. \pnum \returns \tcode{*this}. @@ -14038,7 +13994,7 @@ \end{itemdescr} -\rSec3[fs.dir.itr.nonmembers]{\tcode{directory_iterator} non-member functions} +\rSec3[fs.dir.itr.nonmembers]{Non-member functions} \pnum These functions enable range access for \tcode{directory_iterator}. @@ -14132,7 +14088,7 @@ \begin{note} If the directory structure being iterated over contains cycles then the end iterator may be unreachable. \end{note} -\rSec3[fs.rec.dir.itr.members]{\tcode{recursive_directory_iterator} members} +\rSec3[fs.rec.dir.itr.members]{Members} \indexlibrary{\idxcode{recursive_directory_iterator}!constructor}% \begin{itemdecl} @@ -14169,7 +14125,7 @@ and does not report an error. \pnum -\postconditions \tcode{options() == options} for the signatures with a +\ensures \tcode{options() == options} for the signatures with a \tcode{directory_options} argument, otherwise \tcode{options() == directory_options::none}. \pnum @@ -14195,7 +14151,7 @@ \effects Constructs an object of class \tcode{recursive_directory_iterator}. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{options() == rhs.options()} \item \tcode{depth() == rhs.depth()} @@ -14213,7 +14169,7 @@ \effects Constructs an object of class \tcode{recursive_directory_iterator}. \pnum -\postconditions \tcode{options()}, \tcode{depth()}, +\ensures \tcode{options()}, \tcode{depth()}, and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. @@ -14230,7 +14186,7 @@ object, the member has no effect. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{options() == rhs.options()} \item \tcode{depth() == rhs.depth()} @@ -14252,7 +14208,7 @@ object, the member has no effect. \pnum -\postconditions \tcode{options()}, \tcode{depth()}, +\ensures \tcode{options()}, \tcode{depth()}, and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. @@ -14358,7 +14314,7 @@ iterated over, and continue iteration over the parent directory. \pnum -\postconditions Any copies of the previous value of \tcode{*this} +\ensures Any copies of the previous value of \tcode{*this} are no longer required to be dereferenceable nor to be in the domain of \tcode{==}. @@ -14373,14 +14329,14 @@ \begin{itemdescr} \pnum -\postconditions \tcode{recursion_pending() == false}. +\ensures \tcode{recursion_pending() == false}. \pnum \begin{note} \tcode{disable_recursion_pending}\tcode{()} is used to prevent unwanted recursion into a directory. \end{note} \end{itemdescr} -\rSec3[fs.rec.dir.itr.nonmembers]{\tcode{recursive_directory_iterator} non-member functions} +\rSec3[fs.rec.dir.itr.nonmembers]{Non-member functions} \pnum These functions enable use of \tcode{recursive_directory_iterator} @@ -14588,6 +14544,15 @@ \item Otherwise, \tcode{copy_file(from, to, options)}. \end{itemize} +\item +Otherwise, if +\begin{codeblock} +is_directory(f) && +(options & copy_options::create_symlinks) != copy_options::none +\end{codeblock} +then report an error with an \tcode{error_code} argument +equal to \tcode{make_error_code(errc::is_a_directory)}. + \item Otherwise, if \begin{codeblock} @@ -14855,7 +14820,7 @@ \effects Establishes the postcondition, as if by POSIX \tcode{symlink()}. \pnum -\postconditions \tcode{new_symlink} resolves to a symbolic link file that +\ensures \tcode{new_symlink} resolves to a symbolic link file that contains an unspecified representation of \tcode{to}. \pnum @@ -14887,7 +14852,7 @@ \effects Establishes the postcondition, as if by POSIX \tcode{link()}. \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{exists(to) \&\& exists(new_hard_link) \&\& equivalent(to, new_hard_link)} \item The contents of the file or directory @@ -14918,7 +14883,7 @@ \effects Establishes the postcondition, as if by POSIX \tcode{symlink()}. \pnum -\postconditions \tcode{new_symlink} resolves to a symbolic link file that +\ensures \tcode{new_symlink} resolves to a symbolic link file that contains an unspecified representation of \tcode{to}. \pnum @@ -14976,7 +14941,7 @@ \effects Establishes the postcondition, as if by POSIX \tcode{chdir()}. \pnum -\postconditions \tcode{equivalent(p, current_path())}. +\ensures \tcode{equivalent(p, current_path())}. \pnum \throws As specified in~\ref{fs.err.report}. @@ -15573,7 +15538,7 @@ resolves to. \end{note} \pnum -\postconditions \tcode{exists(symlink_status(p))} is \tcode{false}. +\ensures \tcode{exists(symlink_status(p))} is \tcode{false}. \pnum \returns \tcode{false} if \tcode{p} did not exist, @@ -15601,7 +15566,7 @@ resolves to. \end{note} \pnum -\postconditions \tcode{exists(symlink_status(p))} is \tcode{false}. +\ensures \tcode{exists(symlink_status(p))} is \tcode{false}. \pnum \returns The number of files removed. The signature with argument @@ -15912,7 +15877,7 @@ \tcode{path()} is returned at the first error occurrence, if any. \pnum -\postconditions The returned path is in normal form\iref{fs.path.generic}. +\ensures The returned path is in normal form\iref{fs.path.generic}. \pnum \remarks Implementations should diff --git a/source/iterators.tex b/source/iterators.tex index b92af7ed13..edf48d7992 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -7,7 +7,8 @@ This Clause describes components that \Cpp{} programs may use to perform iterations over containers\iref{containers}, streams\iref{iostream.format}, -and stream buffers\iref{stream.buffers}. +stream buffers\iref{stream.buffers}, +and other ranges\iref{ranges}. \pnum The following subclauses describe @@ -19,14 +20,427 @@ as summarized in \tref{iterators.lib.summary}. \begin{libsumtab}{Iterators library summary}{tab:iterators.lib.summary} -\ref{iterator.requirements} & Requirements & \\ \rowsep -\ref{iterator.primitives} & Iterator primitives & \tcode{} \\ +\ref{iterator.requirements} & Iterator requirements & \tcode{} \\ +\ref{iterator.primitives} & Iterator primitives & \\ \ref{predef.iterators} & Iterator adaptors & \\ \ref{stream.iterators} & Stream iterators & \\ \ref{iterator.range} & Range access & \\ \ref{iterator.container} & Container and view access & \\ \end{libsumtab} +\rSec1[iterator.synopsis]{Header \tcode{}\ synopsis} + +\indexhdr{iterator}% +\indexlibrary{\idxcode{default_sentinel}}% +\begin{codeblock} +#include + +namespace std { + template using @\placeholder{with-reference}@ = T&; // \expos + template concept @\placeholder{can-reference}@ // \expos + = requires { typename @\placeholdernc{with-reference}@; }; + template concept @\placeholder{dereferenceable}@ // \expos + = requires(T& t) { + { *t } -> @\placeholder{can-reference}@; // not required to be equality-preserving + }; + + // \ref{iterator.assoc.types}, associated types + // \ref{incrementable.traits}, incrementable traits + template struct incrementable_traits; + template + using iter_difference_t = @\seebelow@; + + // \ref{readable.traits}, readable traits + template struct readable_traits; + template + using iter_value_t = @\seebelow@; + + // \ref{iterator.traits}, iterator traits + template struct iterator_traits; + template struct iterator_traits; + + template<@\placeholder{dereferenceable}@ T> + using iter_reference_t = decltype(*declval()); + + namespace ranges { + // \ref{iterator.cust}, customization points + inline namespace @\unspec@ { + // \ref{iterator.cust.move}, \tcode{iter_move} + inline constexpr @\unspec@ iter_move = @\unspec@; + + // \ref{iterator.cust.swap}, \tcode{iter_swap} + inline constexpr @\unspec@ iter_swap = @\unspec@; + } + } + + template<@\placeholder{dereferenceable}@ T> + requires requires(T& t) { + { ranges::iter_move(t) } -> @\placeholder{can-reference}@; + } + using iter_rvalue_reference_t + = decltype(ranges::iter_move(declval())); + + // \ref{iterator.concepts}, iterator concepts + // \ref{iterator.concept.readable}, concept \tcode{Readable} + template + concept Readable = @\seebelow@; + + template + using iter_common_reference_t = + common_reference_t, iter_value_t&>; + + // \ref{iterator.concept.writable}, concept \tcode{Writable} + template + concept Writable = @\seebelow@; + + // \ref{iterator.concept.winc}, concept \tcode{WeaklyIncrementable} + template + concept WeaklyIncrementable = @\seebelow@; + + // \ref{iterator.concept.inc}, concept \tcode{Incrementable} + template + concept Incrementable = @\seebelow@; + + // \ref{iterator.concept.iterator}, concept \tcode{Iterator} + template + concept Iterator = @\seebelow@; + + // \ref{iterator.concept.sentinel}, concept \tcode{Sentinel} + template + concept Sentinel = @\seebelow@; + + // \ref{iterator.concept.sizedsentinel}, concept \tcode{SizedSentinel} + template + inline constexpr bool disable_sized_sentinel = false; + + template + concept SizedSentinel = @\seebelow@; + + // \ref{iterator.concept.input}, concept \tcode{InputIterator} + template + concept InputIterator = @\seebelow@; + + // \ref{iterator.concept.output}, concept \tcode{OutputIterator} + template + concept OutputIterator = @\seebelow@; + + // \ref{iterator.concept.forward}, concept \tcode{ForwardIterator} + template + concept ForwardIterator = @\seebelow@; + + // \ref{iterator.concept.bidir}, concept \tcode{BidirectionalIterator} + template + concept BidirectionalIterator = @\seebelow@; + + // \ref{iterator.concept.random.access}, concept \tcode{RandomAccessIterator} + template + concept RandomAccessIterator = @\seebelow@; + + // \ref{iterator.concept.contiguous}, concept \tcode{ContiguousIterator} + template + concept ContiguousIterator = @\seebelow@; + + // \ref{indirectcallable}, indirect callable requirements + // \ref{indirectcallable.indirectinvocable}, indirect callables + template + concept IndirectUnaryInvocable = @\seebelow@; + + template + concept IndirectRegularUnaryInvocable = @\seebelow@; + + template + concept IndirectUnaryPredicate = @\seebelow@; + + template + concept IndirectRelation = @\seebelow@; + + template + concept IndirectStrictWeakOrder = @\seebelow@; + + template + requires (Readable && ...) && Invocable...> + using indirect_result_t = invoke_result_t...>; + + // \ref{projected}, projected + template Proj> + struct projected; + + template + struct incrementable_traits>; + + // \ref{alg.req}, common algorithm requirements + // \ref{alg.req.ind.move}, concept \tcode{IndirectlyMovable} + template + concept IndirectlyMovable = @\seebelow@; + + template + concept IndirectlyMovableStorable = @\seebelow@; + + // \ref{alg.req.ind.copy}, concept \tcode{IndirectlyCopyable} + template + concept IndirectlyCopyable = @\seebelow@; + + template + concept IndirectlyCopyableStorable = @\seebelow@; + + // \ref{alg.req.ind.swap}, concept \tcode{IndirectlySwappable} + template + concept IndirectlySwappable = @\seebelow@; + + // \ref{alg.req.ind.cmp}, concept \tcode{IndirectlyComparable} + template + concept IndirectlyComparable = @\seebelow@; + + // \ref{alg.req.permutable}, concept \tcode{Permutable} + template + concept Permutable = @\seebelow@; + + // \ref{alg.req.mergeable}, concept \tcode{Mergeable} + template, class P1 = identity, class P2 = identity> + concept Mergeable = @\seebelow@; + + // \ref{alg.req.sortable}, concept \tcode{Sortable} + template, class P = identity> + concept Sortable = @\seebelow@; + + // \ref{iterator.primitives}, primitives + // \ref{std.iterator.tags}, iterator tags + struct input_iterator_tag { }; + struct output_iterator_tag { }; + struct forward_iterator_tag: public input_iterator_tag { }; + struct bidirectional_iterator_tag: public forward_iterator_tag { }; + struct random_access_iterator_tag: public bidirectional_iterator_tag { }; + struct contiguous_iterator_tag: public random_access_iterator_tag { }; + + // \ref{iterator.operations}, iterator operations + template + constexpr void + advance(InputIterator& i, Distance n); + template + constexpr typename iterator_traits::difference_type + distance(InputIterator first, InputIterator last); + template + constexpr InputIterator + next(InputIterator x, + typename iterator_traits::difference_type n = 1); + template + constexpr BidirectionalIterator + prev(BidirectionalIterator x, + typename iterator_traits::difference_type n = 1); + + // \ref{range.iter.ops}, range iterator operations + namespace ranges { + // \ref{range.iter.op.advance}, \tcode{ranges::advance} + template + constexpr void advance(I& i, iter_difference_t n); + template S> + constexpr void advance(I& i, S bound); + template S> + constexpr iter_difference_t advance(I& i, iter_difference_t n, S bound); + + // \ref{range.iter.op.distance}, \tcode{ranges::distance} + template S> + constexpr iter_difference_t distance(I first, S last); + template + constexpr iter_difference_t> distance(R&& r); + + // \ref{range.iter.op.next}, \tcode{ranges::next} + template + constexpr I next(I x); + template + constexpr I next(I x, iter_difference_t n); + template S> + constexpr I next(I x, S bound); + template S> + constexpr I next(I x, iter_difference_t n, S bound); + + // \ref{range.iter.op.prev}, \tcode{ranges::prev} + template + constexpr I prev(I x); + template + constexpr I prev(I x, iter_difference_t n); + template + constexpr I prev(I x, iter_difference_t n, I bound); + } + + // \ref{predef.iterators}, predefined iterators and sentinels + // \ref{reverse.iterators}, reverse iterators + template class reverse_iterator; + + template + constexpr bool operator==( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator!=( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator<( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator>( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator<=( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator>=( + const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr auto operator-( + const reverse_iterator& x, + const reverse_iterator& y) -> decltype(y.base() - x.base()); + template + constexpr reverse_iterator + operator+( + typename reverse_iterator::difference_type n, + const reverse_iterator& x); + + template + constexpr reverse_iterator make_reverse_iterator(Iterator i); + + // \ref{insert.iterators}, insert iterators + template class back_insert_iterator; + template + constexpr back_insert_iterator back_inserter(Container& x); + + template class front_insert_iterator; + template + constexpr front_insert_iterator front_inserter(Container& x); + + template class insert_iterator; + template + constexpr insert_iterator + inserter(Container& x, iterator_t i); + + // \ref{move.iterators}, move iterators and sentinels + template class move_iterator; + template + constexpr bool operator==( + const move_iterator& x, const move_iterator& y); + template + constexpr bool operator!=( + const move_iterator& x, const move_iterator& y); + template + constexpr bool operator<( + const move_iterator& x, const move_iterator& y); + template + constexpr bool operator>( + const move_iterator& x, const move_iterator& y); + template + constexpr bool operator<=( + const move_iterator& x, const move_iterator& y); + template + constexpr bool operator>=( + const move_iterator& x, const move_iterator& y); + + template + constexpr auto operator-( + const move_iterator& x, + const move_iterator& y) -> decltype(x.base() - y.base()); + template + constexpr move_iterator operator+( + typename move_iterator::difference_type n, const move_iterator& x); + template + constexpr move_iterator make_move_iterator(Iterator i); + + template class move_sentinel; + + // \ref{iterators.common}, common iterators + template S> + requires (!Same) + class common_iterator; + + template + struct incrementable_traits>; + + template + struct iterator_traits>; + + // \ref{default.sentinels}, default sentinels + struct default_sentinel_t; + inline constexpr default_sentinel_t default_sentinel{}; + + // \ref{iterators.counted}, counted iterators + template class counted_iterator; + + template + struct incrementable_traits>; + + template + struct iterator_traits>; + + // \ref{unreachable.sentinels}, unreachable sentinels + struct unreachable_sentinel_t; + inline constexpr unreachable_sentinel_t unreachable_sentinel{}; + + // \ref{stream.iterators}, stream iterators + template, + class Distance = ptrdiff_t> + class istream_iterator; + template + bool operator==(const istream_iterator& x, + const istream_iterator& y); + template + bool operator!=(const istream_iterator& x, + const istream_iterator& y); + + template> + class ostream_iterator; + + template> + class istreambuf_iterator; + template + bool operator==(const istreambuf_iterator& a, + const istreambuf_iterator& b); + template + bool operator!=(const istreambuf_iterator& a, + const istreambuf_iterator& b); + + template> + class ostreambuf_iterator; + + // \ref{iterator.range}, range access + template constexpr auto begin(C& c) -> decltype(c.begin()); + template constexpr auto begin(const C& c) -> decltype(c.begin()); + template constexpr auto end(C& c) -> decltype(c.end()); + template constexpr auto end(const C& c) -> decltype(c.end()); + template constexpr T* begin(T (&array)[N]) noexcept; + template constexpr T* end(T (&array)[N]) noexcept; + template constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) + -> decltype(std::begin(c)); + template constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) + -> decltype(std::end(c)); + template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); + template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); + template constexpr auto rend(C& c) -> decltype(c.rend()); + template constexpr auto rend(const C& c) -> decltype(c.rend()); + template constexpr reverse_iterator rbegin(T (&array)[N]); + template constexpr reverse_iterator rend(T (&array)[N]); + template constexpr reverse_iterator rbegin(initializer_list il); + template constexpr reverse_iterator rend(initializer_list il); + template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); + template constexpr auto crend(const C& c) -> decltype(std::rend(c)); + + // \ref{iterator.container}, container access + template constexpr auto size(const C& c) -> decltype(c.size()); + template constexpr size_t size(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; + template constexpr auto data(C& c) -> decltype(c.data()); + template constexpr auto data(const C& c) -> decltype(c.data()); + template constexpr T* data(T (&array)[N]) noexcept; + template constexpr const E* data(initializer_list il) noexcept; +} +\end{codeblock} \rSec1[iterator.requirements]{Iterator requirements} @@ -35,7 +449,7 @@ \pnum \indextext{requirements!iterator}% Iterators are a generalization of pointers that allow a \Cpp{} program to work with different data structures -(containers) in a uniform manner. +(for example, containers and ranges) in a uniform manner. To be able to construct template algorithms that work correctly and efficiently on different types of data structures, the library formalizes not just the interfaces but also the semantics and complexity assumptions of iterators. @@ -52,47 +466,56 @@ \defn{writable} to the iterator; for each such type \tcode{T}, the expression \tcode{*i = o} is valid where \tcode{o} is a value of type \tcode{T}. -An iterator -\tcode{i} -for which the expression -\tcode{(*i).m} -is well-defined supports the expression -\tcode{i->m} -with the same semantics as -\tcode{(*i).m}. For every iterator type -\tcode{X} -for which -equality is defined, there is a corresponding signed integer type called the +\tcode{X}, +there is a corresponding signed integer type called the \term{difference type} of the iterator. \pnum -Since iterators are an abstraction of pointers, their semantics is +Since iterators are an abstraction of pointers, their semantics are a generalization of most of the semantics of pointers in \Cpp{}. This ensures that every function template that takes iterators works as well with regular pointers. This document defines -five categories of iterators, according to the operations +six categories of iterators, according to the operations defined on them: \term{input iterators}, \term{output iterators}, \term{forward iterators}, -\term{bidirectional iterators} -and +\term{bidirectional iterators}, \term{random access iterators}, +and +\term{contiguous iterators}, as shown in \tref{iterators.relations}. \begin{floattable}{Relations among iterator categories}{tab:iterators.relations} -{llll} +{lllll} \topline -\textbf{Random Access} & $\rightarrow$ \textbf{Bidirectional} & -$\rightarrow$ \textbf{Forward} & $\rightarrow$ \textbf{Input} \\ - & & & $\rightarrow$ \textbf{Output} \\ +\textbf{Contiguous} & +$\rightarrow$ \textbf{Random Access} & +$\rightarrow$ \textbf{Bidirectional} & +$\rightarrow$ \textbf{Forward} & +$\rightarrow$ \textbf{Input} \\ +&&&& +$\rightarrow$ \textbf{Output} \\ \end{floattable} +\pnum +The six categories of iterators correspond to the iterator concepts +\libconcept{Input\-Iterator}\iref{iterator.concept.input}, +\libconcept{Output\-Iterator}\iref{iterator.concept.output}, +\libconcept{Forward\-Iterator}\iref{iterator.concept.forward}, +\libconcept{Bidirectional\-Iterator}\iref{iterator.concept.bidir} +\libconcept{RandomAccess\-Iterator}\iref{iterator.concept.random.access}, +and +\libconcept{Contiguous\-Iterator}\iref{iterator.concept.contiguous}, +respectively. +The generic term \defn{iterator} refers to any type that models the +\libconcept{Iterator} concept\iref{iterator.concept.iterator}. + \pnum Forward iterators satisfy all the requirements of input iterators and can be used whenever @@ -100,7 +523,9 @@ Bidirectional iterators also satisfy all the requirements of forward iterators and can be used whenever a forward iterator is specified; Random access iterators also satisfy all the requirements of bidirectional -iterators and can be used whenever a bidirectional iterator is specified. +iterators and can be used whenever a bidirectional iterator is specified; +Contiguous iterators also satisfy all the requirements of random access +iterators and can be used whenever a random access iterator is specified. \pnum Iterators that further satisfy the requirements of output iterators are @@ -115,21 +540,6 @@ (in which case \tcode{iterator_traits} pick them up automatically), or an \tcode{iterator_traits} specialization must provide them. \end{note} -\pnum -Iterators that further satisfy the requirement that, -for integral values \tcode{n} and -dereferenceable iterator values \tcode{a} and \tcode{(a + n)}, -\tcode{*(a + n)} is equivalent to \tcode{*(addressof(*a) + n)}, -are called \defn{contiguous iterators}. -\begin{note} -For example, the type ``pointer to \tcode{int}'' is a contiguous iterator, -but \tcode{reverse_iterator} is not. -For a valid iterator range $[$\tcode{a}$, $\tcode{b}$)$ with dereferenceable \tcode{a}, -the corresponding range denoted by pointers is -$[$\tcode{addressof(*a)}$, $\tcode{addressof(*a) + (b - a)}$)$; -\tcode{b} might not be dereferenceable. -\end{note} - \pnum Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element of the array, so for any iterator type there is an iterator value that points past the last element of a @@ -169,51 +579,51 @@ values are always non-singular. \pnum -An iterator -\tcode{j} -is called -\term{reachable} -from an iterator -\tcode{i} -if and only if there is a finite sequence of applications of -the expression -\tcode{++i} -that makes -\tcode{i == j}. -If -\tcode{j} -is reachable from -\tcode{i}, -they refer to elements of the same sequence. - -\pnum -Most of the library's algorithmic templates that operate on data structures have interfaces that use ranges. -A -\term{range} -is a pair of iterators that designate the beginning and end of the computation. -A range \range{i}{i} -is an empty range; -in general, a range \range{i}{j} +Most of the library's algorithmic templates that operate on data structures have +interfaces that use ranges. A \term{range} is an iterator and a \term{sentinel} +that designate the beginning and end of the computation, or an iterator and a +count that designate the beginning and the number of elements to which the +computation is to be applied.\footnote{The sentinel denoting the end of a range +may have the same type as the iterator denoting the beginning of the range, or a +different type.} + +\pnum +An iterator and a sentinel denoting a range are comparable. +A range \range{i}{s} +is empty if \tcode{i == s}; +otherwise, \range{i}{s} refers to the elements in the data structure starting with the element pointed to by \tcode{i} -and up to but not including the element pointed to by -\tcode{j}. -Range \range{i}{j} -is valid if and only if -\tcode{j} -is reachable from -\tcode{i}. -The result of the application of functions in the library to invalid ranges is -undefined. +and up to but not including the element, if any, pointed to by +the first iterator \tcode{j} such that \tcode{j == s}. + +\pnum +A sentinel \tcode{s} is called \term{reachable} from an iterator \tcode{i} if +and only if there is a finite sequence of applications of the expression +\tcode{++i} that makes \tcode{i == s}. If \tcode{s} is reachable from \tcode{i}, +\range{i}{s} denotes a valid range. + +\pnum +A counted range \range{i}{n} is empty if \tcode{n == 0}; otherwise, \range{i}{n} +refers to the \tcode{n} elements in the data structure starting with the element +pointed to by \tcode{i} and up to but not including the element, if any, pointed to by +the result of \tcode{n} applications of \tcode{++i}. A counted range +\range{i}{n} is valid if and only if \tcode{n == 0}; or \tcode{n} is positive, +\tcode{i} is dereferenceable, and \range{++i}{-{-}n} is valid. + +\pnum +The result of the application of library functions +to invalid ranges is undefined. \pnum All the categories of iterators require only those functions that are realizable for a given category in constant time (amortized). -Therefore, requirement tables for the iterators do not have a complexity column. +Therefore, requirement tables and concept definitions for the iterators +do not specify complexity. \pnum -Destruction of an iterator may invalidate pointers and references +Destruction of a non-forward iterator may invalidate pointers and references previously obtained from that iterator. \pnum @@ -227,10 +637,10 @@ \pnum \indextext{iterator!constexpr}% Iterators are called \defn{constexpr iterators} -if all operations provided to satisfy iterator category operations +if all operations provided to meet iterator category requirements are constexpr functions, except for \begin{itemize} -\item a pseudo-destructor call\iref{expr.pseudo}, and +\item a pseudo-destructor call\iref{expr.prim.id.dtor}, and \item the construction of an iterator with a singular value. \end{itemize} \begin{note} @@ -238,1204 +648,3561 @@ \tcode{reverse_iterator} are constexpr iterators. \end{note} +\rSec2[iterator.assoc.types]{Associated types} + +\rSec3[incrementable.traits]{Incrementable traits} + \pnum -In the following subclauses, -\tcode{a} -and -\tcode{b} -denote values of type -\tcode{X} or \tcode{const X}, -\tcode{difference_type} and \tcode{reference} refer to the -types \tcode{iterator_traits::difference_type} and -\tcode{iterator_traits::reference}, respectively, -\tcode{n} -denotes a value of -\tcode{difference_type}, -\tcode{u}, -\tcode{tmp}, -and -\tcode{m} -denote identifiers, -\tcode{r} -denotes a value of -\tcode{X\&}, -\tcode{t} -denotes a value of value type -\tcode{T}, -\tcode{o} -denotes a value of some type that is writable to the output iterator. -\begin{note} For an iterator type \tcode{X} there must be an instantiation -of \tcode{iterator_traits}\iref{iterator.traits}. \end{note} +To implement algorithms only in terms of incrementable types, +it is often necessary to determine the difference type that +corresponds to a particular incrementable type. Accordingly, +it is required that if \tcode{WI} is the name of a type that models the +\tcode{WeaklyIncrementable} concept\iref{iterator.concept.winc}, +the type +\begin{codeblock} +iter_difference_t +\end{codeblock} +be defined as the incrementable type's difference type. -\rSec2[iterator.iterators]{\oldconcept{Iterator}} +\indexlibrary{\idxcode{incrementable_traits}}% +\begin{codeblock} +namespace std { + template struct incrementable_traits { }; -\pnum -The \oldconcept{Iterator} requirements form the basis of the iterator -taxonomy; every iterator satisfies the \oldconcept{Iterator} requirements. This -set of requirements specifies operations for dereferencing and incrementing -an iterator. Most algorithms will require additional operations to -read\iref{input.iterators} or write\iref{output.iterators} values, or -to provide a richer set of iterator movements~(\ref{forward.iterators}, -\ref{bidirectional.iterators}, \ref{random.access.iterators}). + template + requires is_object_v + struct incrementable_traits { + using difference_type = ptrdiff_t; + }; -\pnum -A type \tcode{X} satisfies the \oldconcept{Iterator} requirements if: + template + struct incrementable_traits + : incrementable_traits { }; -\begin{itemize} -\item \tcode{X} satisfies the \oldconcept{CopyConstructible}, \oldconcept{CopyAssignable}, and -\oldconcept{Destructible} requirements\iref{utility.arg.requirements} and lvalues -of type \tcode{X} are swappable\iref{swappable.requirements}, and + template + requires requires { typename T::difference_type; } + struct incrementable_traits { + using difference_type = typename T::difference_type; + }; -\item the expressions in \tref{iterator.requirements} are valid and have -the indicated semantics. -\end{itemize} + template + requires (!requires { typename T::difference_type; } && + requires(const T& a, const T& b) { { a - b } -> Integral; }) + struct incrementable_traits { + using difference_type = make_signed_t() - declval())>; + }; -\begin{libreqtab4b} -{\oldconcept{Iterator} requirements} -{tab:iterator.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead + template + using iter_difference_t = @\seebelow@; +} +\end{codeblock} -\tcode{*r} & - unspecified & - & - \requires \tcode{r} is dereferenceable. \\ \rowsep +\indexlibrary{\idxcode{iter_difference_t}}% +\pnum +The type \tcode{iter_difference_t} denotes +\begin{itemize} +\item +\tcode{incrementable_traits::difference_type} +if \tcode{iterator_traits} names a specialization +generated from the primary template, and -\tcode{++r} & - \tcode{X\&} & - & - \\ +\item +\tcode{iterator_traits::\brk{}difference_type} otherwise. +\end{itemize} -\end{libreqtab4b} +\pnum +Users may specialize \tcode{incrementable_traits} on program-defined types. -\rSec2[input.iterators]{Input iterators} +\rSec3[readable.traits]{Readable traits} \pnum -A class or pointer type -\tcode{X} -satisfies the requirements of an input iterator for the value type -\tcode{T} -if -\tcode{X} satisfies the \oldconcept{Iterator}\iref{iterator.iterators} and -\oldconcept{EqualityComparable} (\tref{equalitycomparable}) requirements and -the expressions in \tref{iterator.input.requirements} are valid and have -the indicated semantics. +To implement algorithms only in terms of readable types, it is often necessary +to determine the value type that corresponds to a particular readable type. +Accordingly, it is required that if \tcode{R} is the name of a type that +models the \tcode{Readable} concept\iref{iterator.concept.readable}, +the type +\begin{codeblock} +iter_value_t +\end{codeblock} +be defined as the readable type's value type. -\pnum -In \tref{iterator.input.requirements}, the term -\term{the domain of \tcode{==}} -is used in the ordinary mathematical sense to denote -the set of values over which -\tcode{==} is (required to be) defined. -This set can change over time. -Each algorithm places additional requirements on the domain of -\tcode{==} for the iterator values it uses. -These requirements can be inferred from the uses that algorithm -makes of \tcode{==} and \tcode{!=}. -\begin{example} -The call \tcode{find(a,b,x)} -is defined only if the value of \tcode{a} -has the property \textit{p} -defined as follows: -\tcode{b} has property \textit{p} -and a value \tcode{i} -has property \textit{p} -if -(\tcode{*i==x}) -or if -(\tcode{*i!=x} -and -\tcode{++i} -has property -\textit{p}). -\end{example} +\indexlibrary{\idxcode{readable_traits}}% +\begin{codeblock} + template struct @\placeholder{cond-value-type}@ { }; // \expos + template + requires is_object_v + struct @\placeholder{cond-value-type}@ { + using value_type = remove_cv_t; + }; -\begin{libreqtab4b} -{\oldconcept{InputIterator} requirements (in addition to \oldconcept{Iterator})} -{tab:iterator.input.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{a != b} & - contextually convertible to \tcode{bool} & - \tcode{!(a == b)} & - \requires \orange{a}{b} is in the domain of \tcode{==}. \\ \rowsep + template struct readable_traits { }; -\tcode{*a} & - \tcode{reference}, convertible to \tcode{T} & - & - \requires \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 -\tcode{++r} & - \tcode{X\&} & - & - \requires \tcode{r} is dereferenceable.\br - \postconditions \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 + template + struct readable_traits + : @\placeholder{cond-value-type}@ { }; -\tcode{(void)r++} & - & - & - equivalent to \tcode{(void)++r} \\ \rowsep + template + requires is_array_v + struct readable_traits { + using value_type = remove_cv_t>; + }; -\tcode{*r++} & - convertible to \tcode{T} & - \tcode{\{ T tmp = *r;}\br - \tcode{++r;}\br - \tcode{return tmp; \}} & \\ -\end{libreqtab4b} + template + struct readable_traits + : readable_traits { }; -\pnum -\begin{note} -For input iterators, -\tcode{a == b} -does not imply -\tcode{++a == ++b}. -(Equality does not guarantee the substitution property or referential transparency.) -Algorithms on input iterators should never attempt to pass through the same iterator twice. -They should be -\term{single pass} -algorithms. -Value type \tcode{T} is not required to be a \oldconcept{CopyAssignable} type (\tref{copyassignable}). -These algorithms can be used with istreams as the source of the input data through the -\tcode{istream_iterator} -class template. -\end{note} + template + requires requires { typename T::value_type; } + struct readable_traits + : @\placeholder{cond-value-type}@ { }; -\rSec2[output.iterators]{Output iterators} + template + requires requires { typename T::element_type; } + struct readable_traits + : @\placeholder{cond-value-type}@ { }; -\pnum -A class or pointer type -\tcode{X} -satisfies the requirements of an output iterator -if \tcode{X} satisfies the \oldconcept{Iterator} requirements\iref{iterator.iterators} -and the expressions in \tref{iterator.output.requirements} -are valid and have the indicated semantics. + template using iter_value_t = @\seebelow@; +\end{codeblock} -\begin{libreqtab4b} -{\oldconcept{OutputIterator} requirements (in addition to \oldconcept{Iterator})} -{tab:iterator.output.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{*r = o} & - result is not used & - & - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br - \postconditions \tcode{r} is incrementable. \\ \rowsep +\indexlibrary{\idxcode{iter_value_t}}% +\pnum +The type \tcode{iter_value_t} denotes +\begin{itemize} +\item +\tcode{readable_traits::value_type} +if \tcode{iterator_traits} names a specialization +generated from the primary template, and -\tcode{++r} & - \tcode{X\&} & - & - \tcode{\&r == \&++r}.\br - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br - \postconditions \tcode{r} is incrementable. \\ \rowsep +\item +\tcode{iterator_traits::value_type} otherwise. +\end{itemize} -\tcode{r++} & - convertible to \tcode{const X\&} & - \tcode{\{ X tmp = r;}\br - \tcode{ ++r;}\br - \tcode{ return tmp; \}} & - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br - \postconditions \tcode{r} is incrementable. \\ \rowsep +\pnum +Class template \tcode{readable_traits} may be specialized +on program-defined types. -\tcode{*r++ = o} & - result is not used && - \remarks\ After this operation \tcode{r} is not required to be dereferenceable.\br - \postconditions \tcode{r} is incrementable. \\ -\end{libreqtab4b} +\pnum +\begin{note} +Some legacy output iterators define a nested type named \tcode{value_type} +that is an alias for \tcode{void}. These types are not \tcode{Readable} +and have no associated value types. +\end{note} \pnum \begin{note} -The only valid use of an -\tcode{operator*} -is on the left side of the assignment statement. -\textit{Assignment through the same value of the iterator happens only once.} -Algorithms on output iterators should never attempt to pass through the same iterator twice. -They should be -\term{single pass} -algorithms. -Equality and inequality might not be defined. +Smart pointers like \tcode{shared_ptr} are \tcode{Readable} and +have an associated value type, but a smart pointer like \tcode{shared_ptr} +is not \tcode{Readable} and has no associated value type. \end{note} -\rSec2[forward.iterators]{Forward iterators} +\rSec3[iterator.traits]{Iterator traits} \pnum -A class or pointer type -\tcode{X} -satisfies the requirements of a forward iterator if +\indexlibrary{\idxcode{iterator_traits}}% +To implement algorithms only in terms of iterators, it is sometimes necessary to +determine the iterator category that corresponds to a particular iterator type. +Accordingly, it is required that if +\tcode{I} +is the type of an iterator, +the type +\indexlibrarymember{iterator_category}{iterator_traits}% +\begin{codeblock} +iterator_traits::iterator_category +\end{codeblock} +be defined as the iterator's iterator category. +In addition, the types +\indexlibrarymember{pointer}{iterator_traits}% +\indexlibrarymember{reference}{iterator_traits}% +\begin{codeblock} +iterator_traits::pointer +iterator_traits::reference +\end{codeblock} +shall be defined as the iterator's pointer and reference types; +that is, for an +iterator object \tcode{a} of class type, +the same type as +\tcode{decltype(a.operator->())} and +\tcode{decltype(*a)}, +respectively. +The type +\tcode{iterator_traits::pointer} +shall be \tcode{void} +for an iterator of class type \tcode{I} +that does not support \tcode{operator->}. +Additionally, in the case of an output iterator, the types +\begin{codeblock} +iterator_traits::value_type +iterator_traits::difference_type +iterator_traits::reference +\end{codeblock} +may be defined as \tcode{void}. -\begin{itemize} -\item \tcode{X} satisfies the \oldconcept{InputIterator} requirements\iref{input.iterators}, +\pnum +The definitions in this subclause make use of the following +exposition-only concepts: -\item \tcode{X} satisfies the \oldconcept{DefaultConstructible} -requirements\iref{utility.arg.requirements}, +\begin{codeblock} +template +concept @\placeholder{cpp17-iterator}@ = + Copyable && requires(I i) { + { *i } -> @\placeholder{can-reference}@; + { ++i } -> Same; + { *i++ } -> @\placeholder{can-reference}@; + }; -\item if \tcode{X} is a mutable iterator, \tcode{reference} is a reference to \tcode{T}; -if \tcode{X} is a constant iterator, \tcode{reference} is a reference to \tcode{const T}, +template +concept @\placeholder{cpp17-input-iterator}@ = + @\placeholder{cpp17-iterator}@ && EqualityComparable && requires(I i) { + typename incrementable_traits::difference_type; + typename readable_traits::value_type; + typename common_reference_t &&, + typename readable_traits::value_type &>; + *i++; + typename common_reference_t::value_type &>; + requires SignedIntegral::difference_type>; + }; -\item the expressions in \tref{iterator.forward.requirements} -are valid and have the indicated semantics, and +template +concept @\placeholder{cpp17-forward-iterator}@ = + @\placeholder{cpp17-input-iterator}@ && Constructible && + is_lvalue_reference_v> && + Same>, typename readable_traits::value_type> && + requires(I i) { + { i++ } -> const I&; + { *i++ } -> Same>; + }; -\item objects of type \tcode{X} offer the multi-pass guarantee, described below. -\end{itemize} +template +concept @\placeholder{cpp17-bidirectional-iterator}@ = + @\placeholder{cpp17-forward-iterator}@ && requires(I i) { + { --i } -> Same; + { i-- } -> const I&; + { *i-- } -> Same>; + }; + +template +concept @\placeholder{cpp17-random-access-iterator}@ = + @\placeholder{cpp17-bidirectional-iterator}@ && StrictTotallyOrdered && + requires(I i, typename incrementable_traits::difference_type n) { + { i += n } -> Same; + { i -= n } -> Same; + { i + n } -> Same; + { n + i } -> Same; + { i - n } -> Same; + { i - i } -> Same; + { i[n] } -> iter_reference_t; + }; +\end{codeblock} \pnum -The domain of \tcode{==} for forward iterators is that of iterators over the same -underlying sequence. However, value-initialized iterators may be compared and -shall compare equal to other value-initialized iterators of the same type. -\begin{note} Value-initialized iterators behave as if they refer past the end of -the same empty sequence. \end{note} +The members of a specialization \tcode{iterator_traits} generated from the +\tcode{iterator_traits} primary template are computed as follows: + +\begin{itemize} +\item +If \tcode{I} has valid\iref{temp.deduct} member +types \tcode{difference_type}, \tcode{value_type}, +\tcode{reference}, and \tcode{iterator_category}, +then +\tcode{iterator_traits} +has the following publicly accessible members: +\begin{codeblock} + using iterator_category = typename I::iterator_category; + using value_type = typename I::value_type; + using difference_type = typename I::difference_type; + using pointer = @\seebelow@; + using reference = typename I::reference; +\end{codeblock} +If the \grammarterm{qualified-id} \tcode{I::pointer} is valid and +denotes a type, then \tcode{iterator_traits::pointer} names that type; +otherwise, it names \tcode{void}. + +\item +Otherwise, if \tcode{I} satisfies the exposition-only concept +\tcode{\placeholder{cpp17-input-iterator}}, +%then +\tcode{iterator_traits} has the following +publicly accessible members: +\begin{codeblock} + using iterator_category = @\seebelow@; + using value_type = typename readable_traits::value_type; + using difference_type = typename incrementable_traits::difference_type; + using pointer = @\seebelow@; + using reference = @\seebelow@; +\end{codeblock} +\begin{itemize} +\item If the \grammarterm{qualified-id} \tcode{I::pointer} is valid and denotes a type, +\tcode{pointer} names that type. Otherwise, if +\tcode{decltype(\brk{}declval().operator->())} is well-formed, then +\tcode{pointer} names that type. Otherwise, \tcode{pointer} +names \tcode{void}. + +\item If the \grammarterm{qualified-id} \tcode{I::reference} is valid and denotes a +type, \tcode{reference} names that type. Otherwise, \tcode{reference} +names \tcode{iter_reference_t}. + +\item If the \grammarterm{qualified-id} \tcode{I::iterator_category} is valid and +denotes a type, \tcode{iterator_category} names that type. +Otherwise, \tcode{iterator_category} names: +\begin{itemize} +\item +\tcode{random_access_iterator_tag} +if +\tcode{I} satisfies \tcode{\placeholder{cpp17-random-access-iterator}}, +or otherwise +\item +\tcode{bidirectional_iterator_tag} if +\tcode{I} satisfies \tcode{\placeholder{cpp17-bidirectional-iterator}}, +or otherwise +\item +\tcode{forward_iterator_tag} if +\tcode{I} satisfies \tcode{\placeholder{cpp17-forward-iterator}}, +or otherwise +\item +\tcode{input_iterator_tag}. +\end{itemize} +\end{itemize} + +\item +Otherwise, if \tcode{I} satisfies the exposition-only concept +\tcode{\placeholder{cpp17-iterator}}, then \tcode{iterator_traits} +has the following publicly accessible +members: +\begin{codeblock} + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = @\seebelow@; + using pointer = void; + using reference = void; +\end{codeblock} +If the \grammarterm{qualified-id} +\tcode{incrementable_traits::difference_type} is valid and denotes a type, +then \tcode{difference_type} names that type; otherwise, it names \tcode{void}. + +\item +Otherwise, \tcode{iterator_traits} +has no members by any of the above names. +\end{itemize} \pnum -Two dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{X} offer the -\defn{multi-pass guarantee} if: +Explicit or partial specializations of \tcode{iterator_traits} may +have a member type \tcode{iterator_concept} that is used to indicate +conformance to the iterator concepts\iref{iterator.concepts}. + +\pnum +\tcode{iterator_traits} is specialized for pointers as + +\begin{codeblock} +namespace std { + template + requires is_object_v + struct iterator_traits { + using iterator_concept = contiguous_iterator_tag; + using iterator_category = random_access_iterator_tag; + using value_type = remove_cv_t; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; + }; +} +\end{codeblock} + +\pnum +\begin{example} +To implement a generic +\tcode{reverse} +function, a \Cpp{} program can do the following: + +\begin{codeblock} +template +void reverse(BI first, BI last) { + typename iterator_traits::difference_type n = + distance(first, last); + --n; + while(n > 0) { + typename iterator_traits::value_type + tmp = *first; + *first++ = *--last; + *last = tmp; + n -= 2; + } +} +\end{codeblock} +\end{example} + +\rSec2[iterator.cust]{Customization points} + +\rSec3[iterator.cust.move]{\tcode{iter_move}} + +\indexlibrary{\idxcode{iter_move}}% +\pnum +The name \tcode{iter_move} denotes +a customization point object\iref{customization.point.object}. +The expression \tcode{ranges::iter_move(E)} for some subexpression \tcode{E} is +expression-equivalent to the following: \begin{itemize} -\item \tcode{a == b} implies \tcode{++a == ++b} and -\item \tcode{X} is a pointer type or the expression -\tcode{(void)++X(a), *a} is equivalent to the expression \tcode{*a}. +\item \tcode{iter_move(E)}, if that expression is valid, with overload +resolution performed in a context that does not include a declaration of +\tcode{ranges::iter_move}. + +\item Otherwise, if the expression \tcode{*E} is well-formed: +\begin{itemize} +\item if \tcode{*E} is an lvalue, \tcode{std::move(*E)}; + +\item otherwise, \tcode{*E}. \end{itemize} -\pnum +\item Otherwise, \tcode{ranges::iter_move(E)} is ill-formed. \begin{note} -The requirement that -\tcode{a == b} -implies -\tcode{++a == ++b} -(which is not true for input and output iterators) -and the removal of the restrictions on the number of the assignments through -a mutable iterator -(which applies to output iterators) -allows the use of multi-pass one-directional algorithms with forward iterators. +This case can result in substitution failure when \tcode{ranges::iter_move(E)} +appears in the immediate context of a template instantiation. \end{note} +\end{itemize} -\begin{libreqtab4b} -{\oldconcept{ForwardIterator} requirements (in addition to \oldconcept{InputIterator})} -{tab:iterator.forward.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{r++} & - convertible to \tcode{const X\&} & - \tcode{\{ X tmp = r;}\br - \tcode{ ++r;}\br - \tcode{ return tmp; \}}& \\ \rowsep +\pnum +If \tcode{ranges::iter_move(E)} is not equal to \tcode{*E}, the program is +ill-formed with no diagnostic required. -\tcode{*r++} & - \tcode{reference} && \\ -\end{libreqtab4b} +\rSec3[iterator.cust.swap]{\tcode{iter_swap}} +\indexlibrary{\idxcode{iter_swap}}% \pnum -If \tcode{a} and \tcode{b} are equal, then either \tcode{a} and \tcode{b} -are both dereferenceable -or else neither is dereferenceable. +The name \tcode{iter_swap} denotes +a customization point object\iref{customization.point.object} +that exchanges the values\iref{concept.swappable} denoted by its +arguments. \pnum -If \tcode{a} and \tcode{b} are both dereferenceable, then \tcode{a == b} -if and only if -\tcode{*a} and \tcode{*b} are bound to the same object. +Let \tcode{\placeholder{iter-exchange-move}} be the exposition-only function: +\begin{itemdecl} +template + constexpr iter_value_t> @\placeholdernc{iter-exchange-move}@(X&& x, Y&& y) + noexcept(noexcept(iter_value_t>(iter_move(x))) && + noexcept(*x = iter_move(y))); +\end{itemdecl} -\rSec2[bidirectional.iterators]{Bidirectional iterators} +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +iter_value_t> old_value(iter_move(x)); +*x = iter_move(y); +return old_value; +\end{codeblock} +\end{itemdescr} \pnum -A class or pointer type -\tcode{X} -satisfies the requirements of a bidirectional iterator if, -in addition to satisfying the \oldconcept{ForwardIterator} requirements, -the following expressions are valid as shown in \tref{iterator.bidirectional.requirements}. +The expression \tcode{ranges::iter_swap(E1, E2)} for some subexpressions +\tcode{E1} and \tcode{E2} is expression-equivalent to the following: -\begin{libreqtab4b} -{\oldconcept{BidirectionalIterator} requirements (in addition to \oldconcept{ForwardIterator})} -{tab:iterator.bidirectional.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{\dcr r} & - \tcode{X\&} & - & - \requires there exists \tcode{s} such that \tcode{r == ++s}.\br - \postconditions \tcode{r} is dereferenceable.\br - \tcode{\dcr(++r) == r}.\br - \tcode{\dcr r == \dcr s} implies \tcode{r == s}.\br - \tcode{\&r == \&\dcr r}. \\ \hline +\begin{itemize} +\item \tcode{(void)iter_swap(E1, E2)}, if that expression is valid, +with overload resolution performed in a context that includes the declaration +\begin{codeblock} +template + void iter_swap(I1, I2) = delete; +\end{codeblock} +and does not include a declaration of \tcode{ranges::iter_swap}. +If the function selected by overload resolution does not exchange the values +denoted by \tcode{E1} and \tcode{E2}, the program is +ill-formed with no diagnostic required. + +\item Otherwise, if the types of \tcode{E1} and \tcode{E2} each model +\tcode{Readable}, and if the reference types of \tcode{E1} and \tcode{E2} +model \libconcept{SwappableWith}\iref{concept.swappable}, +then \tcode{ranges::swap(*E1, *E2)}. + +\item Otherwise, if the types \tcode{T1} and \tcode{T2} of \tcode{E1} and +\tcode{E2} model \tcode{IndirectlyMovableStorable} and +\tcode{IndirectlyMovableStorable}, then +\tcode{(void)(*E1 = \placeholdernc{iter-exchange-move}(E2, E1))}, +except that \tcode{E1} is evaluated only once. + +\item Otherwise, \tcode{ranges::iter_swap(E1, E2)} is ill-formed. +\begin{note} +This case can result in substitution failure when \tcode{ranges::iter_swap(E1, E2)} +appears in the immediate context of a template instantiation. +\end{note} +\end{itemize} -\tcode{r\dcr} & - convertible to \tcode{const X\&} & - \tcode{\{ X tmp = r;}\br - \tcode{ \dcr r;}\br - \tcode{ return tmp; \}}& \\ \rowsep +\rSec2[iterator.concepts]{Iterator concepts} -\tcode{*r\dcr} & - \tcode{reference} && \\ -\end{libreqtab4b} +\rSec3[iterator.concepts.general]{General} + +\pnum +For a type \tcode{I}, let \tcode{\placeholdernc{ITER_TRAITS}(I)} denote +the type \tcode{I} if \tcode{iterator_traits} names +a specialization generated from the primary template. +Otherwise, \tcode{\placeholdernc{ITER_TRAITS}(I)} denotes +\tcode{iterator_traits}. +\begin{itemize} +\item If the \grammarterm{qualified-id} + \tcode{\placeholdernc{ITER_TRAITS}(I)::iterator_concept} is valid + and names a type, then \tcode{\placeholdernc{ITER_CONCEPT}(I)} denotes that + type. +\item Otherwise, if the \grammarterm{qualified-id} + \tcode{\placeholdernc{ITER_TRAITS}(I)\brk{}::iterator_category} + is valid and names a type, then \tcode{\placeholdernc{ITER_CONCEPT}(I)} + denotes that type. +\item Otherwise, if \tcode{iterator_traits} names a specialization generated + from the primary template, then \tcode{\placeholdernc{ITER_CONCEPT}(I)} + denotes \tcode{random_access_iterator_tag}. +\item Otherwise, \tcode{\placeholdernc{ITER_CONCEPT}(I)} does not denote a type. +\end{itemize} \pnum \begin{note} -Bidirectional iterators allow algorithms to move iterators backward as well as forward. +\tcode{\placeholdernc{ITER_TRAITS}} enables independent syntactic determination +of an iterator's category and concept. \end{note} +\begin{example} +\begin{codeblock} +struct I { + using value_type = int; + using difference_type = int; + + int operator*() const; + I& operator++(); + I operator++(int); + I& operator--(); + I operator--(int); + + bool operator==(I) const; + bool operator!=(I) const; +}; +\end{codeblock} +\tcode{iterator_traits::iterator_category} denotes \tcode{input_iterator_tag}, +and \tcode{\placeholder{ITER_CONCEPT}(I)} denotes \tcode{random_access_iterator_tag}. +\end{example} -\rSec2[random.access.iterators]{Random access iterators} +\rSec3[iterator.concept.readable]{Concept \libconcept{Readable}} \pnum -A class or pointer type -\tcode{X} -satisfies the requirements of a random access iterator if, -in addition to satisfying the \oldconcept{BidirectionalIterator} requirements, -the following expressions are valid as shown in \tref{iterator.random.access.requirements}. +Types that are readable by applying \tcode{operator*} +model the \libconcept{Readable} concept, including +pointers, smart pointers, and iterators. -\begin{libreqtab4b} -{\oldconcept{RandomAccessIterator} requirements (in addition to \oldconcept{BidirectionalIterator})} -{tab:iterator.random.access.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ - & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{r += n} & - \tcode{X\&} & - \tcode{\{ difference_type m = n;}\br - \tcode{ if (m >= 0)}\br - \tcode{ while (m\dcr)}\br - \tcode{ ++r;}\br - \tcode{ else}\br - \tcode{ while (m++)}\br - \tcode{ \dcr r;}\br - \tcode{ return r; \}}& \\ \rowsep +\indexlibrary{\idxcode{Readable}}% +\begin{codeblock} +template + concept Readable = + requires { + typename iter_value_t; + typename iter_reference_t; + typename iter_rvalue_reference_t; + } && + CommonReference&&, iter_value_t&> && + CommonReference&&, iter_rvalue_reference_t&&> && + CommonReference&&, const iter_value_t&>; +\end{codeblock} -\tcode{a + n}\br -\tcode{n + a} & - \tcode{X} & - \tcode{\{ X tmp = a;}\br - \tcode{ return tmp += n; \}} & - \tcode{a + n == n + a}. \\ \rowsep +\pnum +Given a value \tcode{i} of type \tcode{I}, \tcode{I} models \libconcept{Readable} +only if the expression \tcode{*i} is equality-preserving. +\begin{note} +The expression \tcode{*i} is indirectly required to be valid via the +exposition-only \placeholder{dereferenceable} concept\iref{iterator.synopsis}. +\end{note} -\tcode{r -= n} & - \tcode{X\&} & - \tcode{return r += -n;} & - \requires the absolute value of \tcode{n} is in the range of - representable values of \tcode{difference_type}. \\ \rowsep +\rSec3[iterator.concept.writable]{Concept \tcode{Writable}} -\tcode{a - n} & - \tcode{X} & - \tcode{\{ X tmp = a;}\br - \tcode{ return tmp -= n; \}} & \\ \rowsep +\pnum +The \tcode{Writable} concept specifies the requirements for writing a value +into an iterator's referenced object. -\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 - \tcode{b == a + (b - a)}. \\ \rowsep +\indexlibrary{\idxcode{Writable}}% +\begin{codeblock} +template + concept Writable = + requires(Out&& o, T&& t) { + *o = std::forward(t); // not required to be equality-preserving + *std::forward(o) = std::forward(t); // not required to be equality-preserving + const_cast&&>(*o) = + std::forward(t); // not required to be equality-preserving + const_cast&&>(*std::forward(o)) = + std::forward(t); // not required to be equality-preserving + }; +\end{codeblock} -\tcode{a[n]} & - convertible to \tcode{reference} & - \tcode{*(a + n)} & \\ \rowsep +\pnum +Let \tcode{E} be an an expression such that \tcode{decltype((E))} is \tcode{T}, +and let \tcode{o} be a dereferenceable object of type \tcode{Out}. +\tcode{Out} and \tcode{T} model \tcode{Writable} only if -\tcode{a < b} & - contextually - convertible to \tcode{bool} & - \tcode{b - a > 0} & - \tcode{<} is a total ordering relation \\ \rowsep +\begin{itemize} +\item If \tcode{Out} and \tcode{T} model + \tcode{Readable \&\& Same, decay_t{>}}, + then \tcode{*o} after any above assignment is equal to + the value of \tcode{E} before the assignment. +\end{itemize} -\tcode{a > b} & - contextually - convertible to \tcode{bool} & - \tcode{b < a} & - \tcode{>} is a total ordering relation opposite to \tcode{<}. \\ \rowsep +\pnum +After evaluating any above assignment expression, \tcode{o} is not required to be dereferenceable. -\tcode{a >= b} & - contextually - convertible to \tcode{bool} & - \tcode{!(a < b)} & \\ \rowsep +\pnum +If \tcode{E} is an xvalue\iref{basic.lval}, the resulting +state of the object it denotes is valid but unspecified\iref{lib.types.movedfrom}. -\tcode{a <= b} & - contextually - convertible to \tcode{bool}. & - \tcode{!(a > b)} & \\ -\end{libreqtab4b} +\pnum +\begin{note} +The only valid use of an \tcode{operator*} is on the left side of the assignment statement. +Assignment through the same value of the writable type happens only once. +\end{note} -\rSec1[iterator.synopsis]{Header \tcode{}\ synopsis} +\pnum +\begin{note} +\tcode{Writable} has the awkward \tcode{const_cast} expressions to reject +iterators with prvalue non-proxy reference types that permit rvalue +assignment but do not also permit \tcode{const} rvalue assignment. +Consequently, an iterator type \tcode{I} that returns \tcode{std::string} +by value does not model \libconcept{Writable}. +\end{note} -\indexhdr{iterator}% -\begin{codeblock} -namespace std { - // \ref{iterator.primitives}, primitives - template struct iterator_traits; - template struct iterator_traits; +\rSec3[iterator.concept.winc]{Concept \tcode{WeaklyIncrementable}} - struct input_iterator_tag { }; - struct output_iterator_tag { }; - struct forward_iterator_tag: public input_iterator_tag { }; - struct bidirectional_iterator_tag: public forward_iterator_tag { }; - struct random_access_iterator_tag: public bidirectional_iterator_tag { }; +\pnum +The \tcode{WeaklyIncrementable} concept specifies the requirements on +types that can be incremented with the pre- and post-increment operators. +The increment operations are not required to be equality-preserving, +nor is the type required to be \libconcept{EqualityComparable}. - // \ref{iterator.operations}, iterator operations - template - constexpr void - advance(InputIterator& i, Distance n); - template - constexpr typename iterator_traits::difference_type - distance(InputIterator first, InputIterator last); - template - constexpr InputIterator - next(InputIterator x, - typename iterator_traits::difference_type n = 1); - template - constexpr BidirectionalIterator - prev(BidirectionalIterator x, - typename iterator_traits::difference_type n = 1); +\indexlibrary{\idxcode{WeaklyIncrementable}}% +\begin{codeblock} +template + concept WeaklyIncrementable = + Semiregular && + requires(I i) { + typename iter_difference_t; + requires SignedIntegral>; + { ++i } -> Same; // not required to be equality-preserving + i++; // not required to be equality-preserving + }; +\end{codeblock} + +\pnum +Let \tcode{i} be an object of type \tcode{I}. When \tcode{i} is in the domain of +both pre- and post-increment, \tcode{i} is said to be \term{incrementable}. +\tcode{I} models \tcode{WeaklyIncrementable} only if + +\begin{itemize} +\item The expressions \tcode{++i} and \tcode{i++} have the same domain. +\item If \tcode{i} is incrementable, then both \tcode{++i} + and \tcode{i++} advance \tcode{i} to the next element. +\item If \tcode{i} is incrementable, then + \tcode{addressof(++i)} is equal to + \tcode{addressof(i)}. +\end{itemize} + +\pnum +\begin{note} +For \tcode{WeaklyIncrementable} types, \tcode{a} equals \tcode{b} does not imply that \tcode{++a} +equals \tcode{++b}. (Equality does not guarantee the substitution property or referential +transparency.) Algorithms on weakly incrementable types should never attempt to pass +through the same incrementable value twice. They should be single-pass algorithms. These algorithms +can be used with istreams as the source of the input data through the \tcode{istream_iterator} class +template. +\end{note} + +\rSec3[iterator.concept.inc]{Concept \tcode{Incrementable}} + +\pnum +The \tcode{Incrementable} concept specifies requirements on types that can be incremented with the pre- +and post-increment operators. The increment operations are required to be equality-preserving, +and the type is required to be \libconcept{EqualityComparable}. +\begin{note} +This supersedes the annotations on the increment expressions +in the definition of \tcode{WeaklyIncrementable}. +\end{note} + +\indexlibrary{\idxcode{Incrementable}}% +\begin{codeblock} +template + concept Incrementable = + Regular && + WeaklyIncrementable && + requires(I i) { + { i++ } -> Same; + }; +\end{codeblock} + +\pnum +Let \tcode{a} and \tcode{b} be incrementable objects of type \tcode{I}. +\tcode{I} models \libconcept{Incrementable} only if + +\begin{itemize} +\item If \tcode{bool(a == b)} then \tcode{bool(a++ == b)}. +\item If \tcode{bool(a == b)} then \tcode{bool(((void)a++, a) == ++b)}. +\end{itemize} + +\pnum +\begin{note} +The requirement that +\tcode{a} equals \tcode{b} +implies +\tcode{++a} equals \tcode{++b} +(which is not true for weakly incrementable types) +allows the use of multi-pass one-directional +algorithms with types that model \libconcept{Increment\-able}. +\end{note} + +\rSec3[iterator.concept.iterator]{Concept \tcode{Iterator}} + +\pnum +The \libconcept{Iterator} concept forms the basis +of the iterator concept taxonomy; every iterator models \libconcept{Iterator}. +This concept specifies operations for dereferencing and incrementing +an iterator. Most algorithms will require additional operations +to compare iterators with sentinels\iref{iterator.concept.sentinel}, to +read\iref{iterator.concept.input} or write\iref{iterator.concept.output} values, or +to provide a richer set of iterator movements (\ref{iterator.concept.forward}, +\ref{iterator.concept.bidir}, \ref{iterator.concept.random.access}). + +\indexlibrary{\idxcode{Iterator}}% +\begin{codeblock} +template + concept Iterator = + requires(I i) { + { *i } -> @\placeholder{can-reference}@; + } && + WeaklyIncrementable; +\end{codeblock} + +\rSec3[iterator.concept.sentinel]{Concept \tcode{Sentinel}} + +\pnum +The \libconcept{Sentinel} concept specifies the relationship +between an \libconcept{Iterator} type and a \libconcept{Semiregular} type +whose values denote a range. + +\indexlibrary{\idxcode{Sentinel}}% +\begin{itemdecl} +template + concept Sentinel = + Semiregular && + Iterator && + @\placeholder{weakly-equality-comparable-with}@; // See \ref{concept.equalitycomparable} +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{s} and \tcode{i} be values of type \tcode{S} and +\tcode{I} such that \range{i}{s} denotes a range. Types +\tcode{S} and \tcode{I} model \tcode{Sentinel} only if + +\begin{itemize} +\item \tcode{i == s} is well-defined. + +\item If \tcode{bool(i != s)} then \tcode{i} is dereferenceable and + \range{++i}{s} denotes a range. +\end{itemize} +\end{itemdescr} + +\pnum +The domain of \tcode{==} is not static. +Given an iterator \tcode{i} and sentinel \tcode{s} such that \range{i}{s} +denotes a range and \tcode{i != s}, \tcode{i} and \tcode{s} are not required to +continue to denote a range after incrementing any other iterator equal +to \tcode{i}. Consequently, \tcode{i == s} is no longer required to be +well-defined. + +\rSec3[iterator.concept.sizedsentinel]{Concept \tcode{SizedSentinel}} + +\pnum +The \libconcept{SizedSentinel} concept specifies +requirements on an \libconcept{Iterator} and a \libconcept{Sentinel} +that allow the use of the \tcode{-} operator to compute the distance +between them in constant time. + +\indexlibrary{\idxcode{SizedSentinel}}% + +\begin{itemdecl} +template + concept SizedSentinel = + Sentinel && + !disable_sized_sentinel, remove_cv_t> && + requires(const I& i, const S& s) { + { s - i } -> Same>; + { i - s } -> Same>; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{i} be an iterator of type \tcode{I}, and \tcode{s} +a sentinel of type \tcode{S} such that \range{i}{s} denotes a range. +Let $N$ be the smallest number of applications of \tcode{++i} +necessary to make \tcode{bool(i == s)} be \tcode{true}. +\tcode{S} and \tcode{I} model \tcode{SizedSentinel} only if + +\begin{itemize} +\item If $N$ is representable by \tcode{iter_difference_t}, + then \tcode{s - i} is well-defined and equals $N$. + +\item If $-N$ is representable by \tcode{iter_difference_t}, + then \tcode{i - s} is well-defined and equals $-N$. +\end{itemize} +\end{itemdescr} + +\pnum +\begin{note} +\tcode{disable_sized_sentinel} allows use of sentinels and iterators with +the library that satisfy but do not in fact model \libconcept{SizedSentinel}. +\end{note} + +\pnum +\begin{example} +The \libconcept{SizedSentinel} concept is modeled by pairs of +\libconcept{RandomAccessIterator}s\iref{iterator.concept.random.access} and by +counted iterators and their sentinels\iref{counted.iterator}. +\end{example} + +\rSec3[iterator.concept.input]{Concept \tcode{InputIterator}} + +\pnum +The \tcode{InputIterator} concept defines requirements for a type +whose referenced values can be read (from the requirement for +\tcode{Readable}\iref{iterator.concept.readable}) and which can be both pre- and +post-incremented. +\begin{note} +Unlike the \oldconcept{InputIterator} requirements\iref{input.iterators}, +the \libconcept{InputIterator} concept does not need +equality comparison since iterators are typically compared to sentinels. +\end{note} + +\indexlibrary{\idxcode{InputIterator}}% +\begin{codeblock} +template + concept InputIterator = + Iterator && + Readable && + requires { typename @\placeholdernc{ITER_CONCEPT}@(I); } && + DerivedFrom<@\placeholdernc{ITER_CONCEPT}@(I), input_iterator_tag>; +\end{codeblock} + +\rSec3[iterator.concept.output]{Concept \tcode{OutputIterator}} + +\pnum +The \tcode{OutputIterator} concept defines requirements for a type that +can be used to write values (from the requirement for +\tcode{Writable}\iref{iterator.concept.writable}) and which can be both pre- and post-incremented. +\begin{note} +Output iterators are not required to model \libconcept{EqualityComparable}. +\end{note} + +\indexlibrary{\idxcode{OutputIterator}}% +\begin{codeblock} +template + concept OutputIterator = + Iterator && + Writable && + requires(I i, T&& t) { + *i++ = std::forward(t); // not required to be equality-preserving + }; +\end{codeblock} + +\pnum +Let \tcode{E} be an expression such that \tcode{decltype((E))} is \tcode{T}, and let \tcode{i} be a +dereferenceable object of type \tcode{I}. \tcode{I} and \tcode{T} model \tcode{OutputIterator} only if +\tcode{*i++ = E;} has effects equivalent to: +\begin{codeblock} + *i = E; + ++i; +\end{codeblock} + +\pnum +\begin{note} +Algorithms on output iterators should never attempt to pass through the same iterator twice. +They should be single-pass algorithms. +\end{note} + +\rSec3[iterator.concept.forward]{Concept \tcode{ForwardIterator}} + +\pnum +The \libconcept{ForwardIterator} concept adds equality comparison and +the multi-pass guarantee, specified below. + +\indexlibrary{\idxcode{ForwardIterator}}% +\begin{codeblock} +template + concept ForwardIterator = + InputIterator && + DerivedFrom<@\placeholdernc{ITER_CONCEPT}@(I), forward_iterator_tag> && + Incrementable && + Sentinel; +\end{codeblock} + +\pnum +The domain of \tcode{==} for forward iterators is that of iterators over the same +underlying sequence. However, value-initialized iterators of the same type +may be compared and shall compare equal to other value-initialized iterators of the same type. +\begin{note} +Value-initialized iterators behave as if they refer past the end of the same +empty sequence. +\end{note} + +\pnum +Pointers and references obtained from a forward iterator into a range \range{i}{s} +shall remain valid while \range{i}{s} continues to denote a range. + +\pnum +Two dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{X} +offer the \defn{multi-pass guarantee} if: + +\begin{itemize} +\item \tcode{a == b} implies \tcode{++a == ++b} and +\item The expression +\tcode{((void)[](X x)\{++x;\}(a), *a)} is equivalent to the expression \tcode{*a}. +\end{itemize} + +\pnum +\begin{note} +The requirement that +\tcode{a == b} +implies +\tcode{++a == ++b} +and the removal of the restrictions on the number of assignments through +a mutable iterator +(which applies to output iterators) +allow the use of multi-pass one-directional algorithms with forward iterators. +\end{note} + +\rSec3[iterator.concept.bidir]{Concept \libconcept{BidirectionalIterator}} + +\pnum +The \libconcept{BidirectionalIterator} concept adds the ability +to move an iterator backward as well as forward. + +\indexlibrary{\idxcode{BidirectionalIterator}}% +\begin{codeblock} +template + concept BidirectionalIterator = + ForwardIterator && + DerivedFrom<@\placeholdernc{ITER_CONCEPT}@(I), bidirectional_iterator_tag> && + requires(I i) { + { --i } -> Same; + { i-- } -> Same; + }; +\end{codeblock} + +\pnum +A bidirectional iterator \tcode{r} is decrementable if and only if there exists some \tcode{q} such that +\tcode{++q == r}. Decrementable iterators \tcode{r} shall be in the domain of the expressions +\tcode{--r} and \tcode{r--}. + +\pnum +Let \tcode{a} and \tcode{b} be equal objects of type \tcode{I}. +\tcode{I} models \libconcept{BidirectionalIterator} only if: + +\begin{itemize} +\item If \tcode{a} and \tcode{b} are decrementable, + then all of the following are \tcode{true}: + \begin{itemize} + \item \tcode{addressof(--a) == addressof(a)} + \item \tcode{bool(a-- == b)} + \item after evaluating both \tcode{a--} and \tcode{--b} + \tcode{bool(a == b)} is still \tcode{true} + \item \tcode{bool(++(--a) == b)} + \end{itemize} + \item If \tcode{a} and \tcode{b} are incrementable, then + \tcode{bool(--(++a) == b)}. +\end{itemize} + +\rSec3[iterator.concept.random.access]{Concept \libconcept{RandomAccessIterator}} + +\pnum +The \libconcept{RandomAccessIterator} concept adds support for +constant-time advancement with \tcode{+=}, \tcode{+}, \tcode{-=}, and \tcode{-}, +as well as the computation of distance in constant time with \tcode{-}. +Random access iterators also support array notation via subscripting. + +\indexlibrary{\idxcode{RandomAccessIterator}}% +\begin{codeblock} +template + concept RandomAccessIterator = + BidirectionalIterator && + DerivedFrom<@\placeholdernc{ITER_CONCEPT}@(I), random_access_iterator_tag> && + StrictTotallyOrdered && + SizedSentinel && + requires(I i, const I j, const iter_difference_t n) { + { i += n } -> Same; + { j + n } -> Same; + { n + j } -> Same; + { i -= n } -> Same; + { j - n } -> Same; + { j[n] } -> Same>; + }; +\end{codeblock} + +\pnum +Let \tcode{a} and \tcode{b} be valid iterators of type \tcode{I} +such that \tcode{b} is reachable from \tcode{a} +after \tcode{n} applications of \tcode{++a}, +let \tcode{D} be \tcode{iter_difference_t}, +and let \tcode{n} denote a value of type \tcode{D}. +\tcode{I} models \libconcept{RandomAccessIterator} only if + +\begin{itemize} +\item \tcode{(a += n)} is equal to \tcode{b}. +\item \tcode{addressof(a += n)} is equal to \tcode{addressof(a)}. +\item \tcode{(a + n)} is equal to \tcode{(a += n)}. +\item For any two positive values + \tcode{x} and \tcode{y} of type \tcode{D}, + if \tcode{(a + D(x + y))} is valid, then + \tcode{(a + D(x + y))} is equal to \tcode{((a + x) + y)}. +\item \tcode{(a + D(0))} is equal to \tcode{a}. +\item If \tcode{(a + D(n - 1))} is valid, then + \tcode{(a + n)} is equal to \tcode{++(a + D(n - 1))}. +\item \tcode{(b += -n)} is equal to \tcode{a}. +\item \tcode{(b -= n)} is equal to \tcode{a}. +\item \tcode{addressof(b -= n)} is equal to \tcode{addressof(b)}. +\item \tcode{(b - n)} is equal to \tcode{(b -= n)}. +\item If \tcode{b} is dereferenceable, then + \tcode{a[n]} is valid and is equal to \tcode{*b}. +\item \tcode{bool(a <= b)} is \tcode{true}. +\end{itemize} + +\rSec3[iterator.concept.contiguous]{Concept \libconcept{ContiguousIterator}} + +\pnum +The \libconcept{ContiguousIterator} concept provides a guarantee that +the denoted elements are stored contiguously in memory. + +\indexlibrary{\idxcode{ContiguousIterator}}% +\begin{codeblock} +template + concept @\libconcept{ContiguousIterator}@ = + RandomAccessIterator && + DerivedFrom<@\placeholdernc{ITER_CONCEPT}@(I), contiguous_iterator_tag> && + is_lvalue_reference_v> && + Same, remove_cvref_t>>; +\end{codeblock} + +\pnum +Let \tcode{a} and \tcode{b} be dereferenceable iterators of type \tcode{I} +such that \tcode{b} is reachable from \tcode{a}, +and let \tcode{D} be \tcode{iter_difference_t}. +The type \tcode{I} models \libconcept{ContiguousIterator} only if +\tcode{addressof(*(a + D(b - a)))} +is equal to +\tcode{addressof(*a) + D(b - a)}. + +\rSec2[iterator.cpp17]{\Cpp{}17 iterator requirements} + +\pnum +In the following sections, +\tcode{a} +and +\tcode{b} +denote values of type +\tcode{X} or \tcode{const X}, +\tcode{difference_type} and \tcode{reference} refer to the +types \tcode{iterator_traits::difference_type} and +\tcode{iterator_traits::reference}, respectively, +\tcode{n} +denotes a value of +\tcode{difference_type}, +\tcode{u}, +\tcode{tmp}, +and +\tcode{m} +denote identifiers, +\tcode{r} +denotes a value of +\tcode{X\&}, +\tcode{t} +denotes a value of value type +\tcode{T}, +\tcode{o} +denotes a value of some type that is writable to the output iterator. +\begin{note} For an iterator type \tcode{X} there must be an instantiation +of \tcode{iterator_traits}\iref{iterator.traits}. \end{note} + +\rSec3[iterator.iterators]{\oldconcept{Iterator}} + +\pnum +The \oldconcept{Iterator} requirements form the basis of the iterator +taxonomy; every iterator satisfies the \oldconcept{Iterator} requirements. This +set of requirements specifies operations for dereferencing and incrementing +an iterator. Most algorithms will require additional operations to +read\iref{input.iterators} or write\iref{output.iterators} values, or +to provide a richer set of iterator movements~(\ref{forward.iterators}, +\ref{bidirectional.iterators}, \ref{random.access.iterators}). + +\pnum +A type \tcode{X} satisfies the \oldconcept{Iterator} requirements if: + +\begin{itemize} +\item \tcode{X} satisfies the \oldconcept{CopyConstructible}, \oldconcept{CopyAssignable}, and +\oldconcept{Destructible} requirements\iref{utility.arg.requirements} and lvalues +of type \tcode{X} are swappable\iref{swappable.requirements}, and + +\item the expressions in \tref{iterator.requirements} are valid and have +the indicated semantics. +\end{itemize} + +\begin{libreqtab4b} +{\oldconcept{Iterator} requirements} +{tab:iterator.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead + +\tcode{*r} & + unspecified & + & + \requires \tcode{r} is dereferenceable. \\ \rowsep + +\tcode{++r} & + \tcode{X\&} & + & + \\ + +\end{libreqtab4b} + +\rSec3[input.iterators]{Input iterators} + +\pnum +A class or pointer type +\tcode{X} +satisfies the requirements of an input iterator for the value type +\tcode{T} +if +\tcode{X} satisfies the \oldconcept{Iterator}\iref{iterator.iterators} and +\oldconcept{EqualityComparable} (\tref{equalitycomparable}) requirements and +the expressions in \tref{iterator.input.requirements} are valid and have +the indicated semantics. + +\pnum +In \tref{iterator.input.requirements}, the term +\term{the domain of \tcode{==}} +is used in the ordinary mathematical sense to denote +the set of values over which +\tcode{==} is (required to be) defined. +This set can change over time. +Each algorithm places additional requirements on the domain of +\tcode{==} for the iterator values it uses. +These requirements can be inferred from the uses that algorithm +makes of \tcode{==} and \tcode{!=}. +\begin{example} +The call \tcode{find(a,b,x)} +is defined only if the value of \tcode{a} +has the property \textit{p} +defined as follows: +\tcode{b} has property \textit{p} +and a value \tcode{i} +has property \textit{p} +if +(\tcode{*i==x}) +or if +(\tcode{*i!=x} +and +\tcode{++i} +has property +\textit{p}). +\end{example} + +\begin{libreqtab4b} +{\oldconcept{InputIterator} requirements (in addition to \oldconcept{Iterator})} +{tab:iterator.input.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead +\tcode{a != b} & + contextually convertible to \tcode{bool} & + \tcode{!(a == b)} & + \requires \orange{a}{b} is in the domain of \tcode{==}. \\ \rowsep + +\tcode{*a} & + \tcode{reference}, convertible to \tcode{T} & + & + \requires \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 +\tcode{++r} & + \tcode{X\&} & + & + \requires \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 + +\tcode{(void)r++} & + & + & + equivalent to \tcode{(void)++r} \\ \rowsep + +\tcode{*r++} & + convertible to \tcode{T} & + \tcode{\{ T tmp = *r;}\br + \tcode{++r;}\br + \tcode{return tmp; \}} & \\ +\end{libreqtab4b} + +\pnum +\begin{note} +For input iterators, +\tcode{a == b} +does not imply +\tcode{++a == ++b}. +(Equality does not guarantee the substitution property or referential transparency.) +Algorithms on input iterators should never attempt to pass through the same iterator twice. +They should be +\term{single pass} +algorithms. +Value type \tcode{T} is not required to be a \oldconcept{CopyAssignable} type (\tref{copyassignable}). +These algorithms can be used with istreams as the source of the input data through the +\tcode{istream_iterator} +class template. +\end{note} + +\rSec3[output.iterators]{Output iterators} + +\pnum +A class or pointer type +\tcode{X} +satisfies the requirements of an output iterator +if \tcode{X} satisfies the \oldconcept{Iterator} requirements\iref{iterator.iterators} +and the expressions in \tref{iterator.output.requirements} +are valid and have the indicated semantics. + +\begin{libreqtab4b} +{\oldconcept{OutputIterator} requirements (in addition to \oldconcept{Iterator})} +{tab:iterator.output.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead +\tcode{*r = o} & + result is not used & + & + \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 + \ensures \tcode{r} is incrementable. \\ \rowsep + +\tcode{r++} & + convertible to \tcode{const X\&} & + \tcode{\{ X tmp = r;}\br + \tcode{ ++r;}\br + \tcode{ return tmp; \}} & + \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 + \ensures \tcode{r} is incrementable. \\ +\end{libreqtab4b} + +\pnum +\begin{note} +The only valid use of an +\tcode{operator*} +is on the left side of the assignment statement. +Assignment through the same value of the iterator happens only once. +Algorithms on output iterators should never attempt to pass through the same iterator twice. +They should be single-pass algorithms. +Equality and inequality might not be defined. +\end{note} + +\rSec3[forward.iterators]{Forward iterators} + +\pnum +A class or pointer type +\tcode{X} +satisfies the requirements of a forward iterator if + +\begin{itemize} +\item \tcode{X} satisfies the \oldconcept{InputIterator} requirements\iref{input.iterators}, + +\item \tcode{X} satisfies the \oldconcept{DefaultConstructible} +requirements\iref{utility.arg.requirements}, + +\item if \tcode{X} is a mutable iterator, \tcode{reference} is a reference to \tcode{T}; +if \tcode{X} is a constant iterator, \tcode{reference} is a reference to \tcode{const T}, + +\item the expressions in \tref{iterator.forward.requirements} +are valid and have the indicated semantics, and + +\item objects of type \tcode{X} offer the multi-pass guarantee, described below. +\end{itemize} + +\pnum +The domain of \tcode{==} for forward iterators is that of iterators over the same +underlying sequence. However, value-initialized iterators may be compared and +shall compare equal to other value-initialized iterators of the same type. +\begin{note} Value-initialized iterators behave as if they refer past the end of +the same empty sequence. \end{note} + +\pnum +Two dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{X} offer the +\defn{multi-pass guarantee} if: + +\begin{itemize} +\item \tcode{a == b} implies \tcode{++a == ++b} and +\item \tcode{X} is a pointer type or the expression +\tcode{(void)++X(a), *a} is equivalent to the expression \tcode{*a}. +\end{itemize} + +\pnum +\begin{note} +The requirement that +\tcode{a == b} +implies +\tcode{++a == ++b} +(which is not true for input and output iterators) +and the removal of the restrictions on the number of the assignments through +a mutable iterator +(which applies to output iterators) +allows the use of multi-pass one-directional algorithms with forward iterators. +\end{note} + +\begin{libreqtab4b} +{\oldconcept{ForwardIterator} requirements (in addition to \oldconcept{InputIterator})} +{tab:iterator.forward.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead +\tcode{r++} & + convertible to \tcode{const X\&} & + \tcode{\{ X tmp = r;}\br + \tcode{ ++r;}\br + \tcode{ return tmp; \}}& \\ \rowsep + +\tcode{*r++} & + \tcode{reference} && \\ +\end{libreqtab4b} + +\pnum +If \tcode{a} and \tcode{b} are equal, then either \tcode{a} and \tcode{b} +are both dereferenceable +or else neither is dereferenceable. + +\pnum +If \tcode{a} and \tcode{b} are both dereferenceable, then \tcode{a == b} +if and only if +\tcode{*a} and \tcode{*b} are bound to the same object. + +\rSec3[bidirectional.iterators]{Bidirectional iterators} + +\pnum +A class or pointer type +\tcode{X} +satisfies the requirements of a bidirectional iterator if, +in addition to satisfying the \oldconcept{ForwardIterator} requirements, +the following expressions are valid as shown in \tref{iterator.bidirectional.requirements}. + +\begin{libreqtab4b} +{\oldconcept{BidirectionalIterator} requirements (in addition to \oldconcept{ForwardIterator})} +{tab:iterator.bidirectional.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead +\tcode{\dcr r} & + \tcode{X\&} & + & + \requires 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 + \tcode{addressof(r) == addressof(\dcr r)}. \\ \hline + +\tcode{r\dcr} & + convertible to \tcode{const X\&} & + \tcode{\{ X tmp = r;}\br + \tcode{ \dcr r;}\br + \tcode{ return tmp; \}}& \\ \rowsep + +\tcode{*r\dcr} & + \tcode{reference} && \\ +\end{libreqtab4b} + +\pnum +\begin{note} +Bidirectional iterators allow algorithms to move iterators backward as well as forward. +\end{note} + +\rSec3[random.access.iterators]{Random access iterators} + +\pnum +A class or pointer type +\tcode{X} +satisfies the requirements of a random access iterator if, +in addition to satisfying the \oldconcept{BidirectionalIterator} requirements, +the following expressions are valid as shown in \tref{iterator.random.access.requirements}. + +\begin{libreqtab4b} +{\oldconcept{RandomAccessIterator} requirements (in addition to \oldconcept{BidirectionalIterator})} +{tab:iterator.random.access.requirements} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ + & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep +\endhead +\tcode{r += n} & + \tcode{X\&} & + \tcode{\{ difference_type m = n;}\br + \tcode{ if (m >= 0)}\br + \tcode{ while (m\dcr)}\br + \tcode{ ++r;}\br + \tcode{ else}\br + \tcode{ while (m++)}\br + \tcode{ \dcr r;}\br + \tcode{ return r; \}}& \\ \rowsep + +\tcode{a + n}\br +\tcode{n + a} & + \tcode{X} & + \tcode{\{ X tmp = a;}\br + \tcode{ return tmp += n; \}} & + \tcode{a + n == n + a}. \\ \rowsep + +\tcode{r -= n} & + \tcode{X\&} & + \tcode{return r += -n;} & + \requires the absolute value of \tcode{n} is in the range of + representable values of \tcode{difference_type}. \\ \rowsep + +\tcode{a - n} & + \tcode{X} & + \tcode{\{ X tmp = a;}\br + \tcode{ return tmp -= n; \}} & \\ \rowsep + +\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 + \tcode{b == a + (b - a)}. \\ \rowsep + +\tcode{a[n]} & + convertible to \tcode{reference} & + \tcode{*(a + n)} & \\ \rowsep + +\tcode{a < b} & + contextually + convertible to \tcode{bool} & + \tcode{b - a > 0} & + \tcode{<} is a total ordering relation \\ \rowsep + +\tcode{a > b} & + contextually + convertible to \tcode{bool} & + \tcode{b < a} & + \tcode{>} is a total ordering relation opposite to \tcode{<}. \\ \rowsep + +\tcode{a >= b} & + contextually + convertible to \tcode{bool} & + \tcode{!(a < b)} & \\ \rowsep + +\tcode{a <= b} & + contextually + convertible to \tcode{bool}. & + \tcode{!(a > b)} & \\ +\end{libreqtab4b} + +\rSec2[indirectcallable]{Indirect callable requirements} + +\rSec3[indirectcallable.general]{General} + +\pnum +There are several concepts that group requirements of algorithms that +take callable objects~(\ref{func.require}) as arguments. + +\rSec3[indirectcallable.indirectinvocable]{Indirect callables} + +\pnum +The indirect callable concepts are used to constrain those algorithms +that accept callable objects~(\ref{func.def}) as arguments. + +\indexlibrary{\idxcode{IndirectUnaryInvocable}}% +\indexlibrary{\idxcode{IndirectRegularUnaryInvocable}}% +\indexlibrary{\idxcode{IndirectUnaryPredicate}}% +\indexlibrary{\idxcode{IndirectRelation}}% +\indexlibrary{\idxcode{IndirectStrictWeakOrder}}% +\begin{codeblock} +namespace std { + template + concept IndirectUnaryInvocable = + Readable && + CopyConstructible && + Invocable&> && + Invocable> && + Invocable> && + CommonReference< + invoke_result_t&>, + invoke_result_t>>; + + template + concept IndirectRegularUnaryInvocable = + Readable && + CopyConstructible && + RegularInvocable&> && + RegularInvocable> && + RegularInvocable> && + CommonReference< + invoke_result_t&>, + invoke_result_t>>; + + template + concept IndirectUnaryPredicate = + Readable && + CopyConstructible && + Predicate&> && + Predicate> && + Predicate>; + + template + concept IndirectRelation = + Readable && Readable && + CopyConstructible && + Relation&, iter_value_t&> && + Relation&, iter_reference_t> && + Relation, iter_value_t&> && + Relation, iter_reference_t> && + Relation, iter_common_reference_t>; + + template + concept IndirectStrictWeakOrder = + Readable && Readable && + CopyConstructible && + StrictWeakOrder&, iter_value_t&> && + StrictWeakOrder&, iter_reference_t> && + StrictWeakOrder, iter_value_t&> && + StrictWeakOrder, iter_reference_t> && + StrictWeakOrder, iter_common_reference_t>; +} +\end{codeblock} + +\rSec3[projected]{Class template \tcode{projected}} + +\pnum +Class template \tcode{projected} is used to constrain algorithms +that accept callable objects and projections\iref{defns.projection}. +It combines a \libconcept{Readable} type \tcode{I} and +a callable object type \tcode{Proj} into a new \libconcept{Readable} type +whose \tcode{reference} type is the result of applying +\tcode{Proj} to the \tcode{iter_reference_t} of \tcode{I}. + +\indexlibrary{\idxcode{projected}}% +\begin{codeblock} +namespace std { + template Proj> + struct projected { + using value_type = remove_cvref_t>; + indirect_result_t operator*() const; // \notdef + }; + + template + struct incrementable_traits> { + using difference_type = iter_difference_t; + }; +} +\end{codeblock} + +\rSec2[alg.req]{Common algorithm requirements} + +\rSec3[alg.req.general]{General} + +\pnum +There are several additional iterator concepts that are commonly applied +to families of algorithms. These group together iterator requirements +of algorithm families. +There are three relational concepts that specify +how element values are transferred between \libconcept{Readable} and +\libconcept{Writable} types: +\libconcept{Indirectly\-Movable}, +\libconcept{Indir\-ect\-ly\-Copy\-able}, and +\libconcept{Indirectly\-Swappable}. +There are three relational concepts for rearrangements: +\libconcept{Permut\-able}, +\libconcept{Mergeable}, and +\libconcept{Sortable}. +There is one relational concept for comparing values from different sequences: +\libconcept{IndirectlyComparable}. + +\pnum +\begin{note} +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} + +\rSec3[alg.req.ind.move]{Concept \libconcept{IndirectlyMovable}} + +\pnum +The \libconcept{IndirectlyMovable} concept specifies the relationship between +a \libconcept{Readable} type and a \libconcept{Writable} type between which +values may be moved. + +\indexlibrary{\idxcode{IndirectlyMovable}}% +\begin{codeblock} +template + concept IndirectlyMovable = + Readable && + Writable>; +\end{codeblock} + +\pnum +The \libconcept{IndirectlyMovableStorable} concept augments +\libconcept{IndirectlyMovable} with additional requirements enabling +the transfer to be performed through an intermediate object of the +\libconcept{Readable} type's value type. + +\indexlibrary{\idxcode{IndirectlyMovableStorable}}% +\begin{codeblock} +template + concept IndirectlyMovableStorable = + IndirectlyMovable && + Writable> && + Movable> && + Constructible, iter_rvalue_reference_t> && + Assignable&, iter_rvalue_reference_t>; +\end{codeblock} + +\pnum +Let \tcode{i} be a dereferenceable value of type \tcode{In}. +\tcode{In} and \tcode{Out} model \tcode{IndirectlyMovableStorable} +only if after the initialization of the object \tcode{obj} in +\begin{codeblock} +iter_value_t obj(ranges::iter_move(i)); +\end{codeblock} +\tcode{obj} is equal to the value previously denoted by \tcode{*i}. If +\tcode{iter_rvalue_reference_t} is an rvalue reference type, +the resulting state of the value denoted by \tcode{*i} is +valid but unspecified\iref{lib.types.movedfrom}. + +\rSec3[alg.req.ind.copy]{Concept \libconcept{IndirectlyCopyable}} + +\pnum +The \libconcept{IndirectlyCopyable} concept specifies the relationship between +a \libconcept{Readable} type and a \libconcept{Writable} type between which +values may be copied. + +\indexlibrary{\idxcode{IndirectlyCopyable}}% +\begin{codeblock} +template + concept IndirectlyCopyable = + Readable && + Writable>; +\end{codeblock} + +\pnum +The \libconcept{IndirectlyCopyableStorable} concept augments +\libconcept{IndirectlyCopyable} with additional requirements enabling +the transfer to be performed through an intermediate object of the +\libconcept{Readable} type's value type. It also requires the capability +to make copies of values. + +\indexlibrary{\idxcode{IndirectlyCopyableStorable}}% +\begin{codeblock} +template + concept IndirectlyCopyableStorable = + IndirectlyCopyable && + Writable&> && + Copyable> && + Constructible, iter_reference_t> && + Assignable&, iter_reference_t>; +\end{codeblock} + +\pnum +Let \tcode{i} be a dereferenceable value of type \tcode{In}. +\tcode{In} and \tcode{Out} model \tcode{IndirectlyCopyableStorable} +only if after the initialization of the object \tcode{obj} in +\begin{codeblock} +iter_value_t obj(*i); +\end{codeblock} +\tcode{obj} is equal to the value previously denoted by \tcode{*i}. If +\tcode{iter_reference_t} is an rvalue reference type, the resulting state +of the value denoted by \tcode{*i} is +valid but unspecified\iref{lib.types.movedfrom}. + +\rSec3[alg.req.ind.swap]{Concept \libconcept{IndirectlySwappable}} + +\pnum +The \libconcept{IndirectlySwappable} concept specifies a swappable relationship +between the values referenced by two \libconcept{Readable} types. + +\indexlibrary{\idxcode{IndirectlySwappable}}% +\begin{codeblock} +template + concept IndirectlySwappable = + Readable && Readable && + requires(I1& i1, I2& i2) { + ranges::iter_swap(i1, i1); + ranges::iter_swap(i2, i2); + ranges::iter_swap(i1, i2); + ranges::iter_swap(i2, i1); + }; +\end{codeblock} + +\rSec3[alg.req.ind.cmp]{Concept \libconcept{IndirectlyComparable}} + +\pnum +The \libconcept{IndirectlyComparable} concept specifies +the common requirements of algorithms that +compare values from two different sequences. + +\indexlibrary{\idxcode{IndirectlyComparable}}% +\begin{codeblock} +template + concept IndirectlyComparable = + IndirectRelation, projected>; +\end{codeblock} + +\rSec3[alg.req.permutable]{Concept \libconcept{Permutable}} + +\pnum +The \libconcept{Permutable} concept specifies the common requirements +of algorithms that reorder elements in place by moving or swapping them. + +\indexlibrary{\idxcode{Permutable}}% +\begin{codeblock} +template + concept Permutable = + ForwardIterator && + IndirectlyMovableStorable && + IndirectlySwappable; +\end{codeblock} + +\rSec3[alg.req.mergeable]{Concept \libconcept{Mergeable}} + +\pnum +The \libconcept{Mergeable} concept specifies the requirements of algorithms +that merge sorted sequences into an output sequence by copying elements. + +\indexlibrary{\idxcode{Mergeable}}% +\begin{codeblock} +template, + class P1 = identity, class P2 = identity> + concept Mergeable = + InputIterator && + InputIterator && + WeaklyIncrementable && + IndirectlyCopyable && + IndirectlyCopyable && + IndirectStrictWeakOrder, projected>; +\end{codeblock} + +\rSec3[alg.req.sortable]{Concept \libconcept{Sortable}} + +\pnum +The \libconcept{Sortable} concept specifies the common requirements of +algorithms that permute sequences into ordered sequences (e.g., \tcode{sort}). + +\indexlibrary{\idxcode{Sortable}}% +\begin{codeblock} +template, class P = identity> + concept Sortable = + Permutable && + IndirectStrictWeakOrder>; +\end{codeblock} + +\rSec1[iterator.primitives]{Iterator primitives} + +\pnum +To simplify the task of defining iterators, the library provides +several classes and functions: + +\rSec2[std.iterator.tags]{Standard iterator tags} + +\pnum +\indexlibrary{\idxcode{output_iterator_tag}}% +\indexlibrary{\idxcode{input_iterator_tag}}% +\indexlibrary{\idxcode{forward_iterator_tag}}% +\indexlibrary{\idxcode{bidirectional_iterator_tag}}% +\indexlibrary{\idxcode{random_access_iterator_tag}}% +\indexlibrary{\idxcode{contiguous_iterator_tag}}% +It is often desirable for a +function template specialization +to find out what is the most specific category of its iterator +argument, so that the function can select the most efficient algorithm at compile time. +To facilitate this, the +library introduces +\term{category tag} +classes which are used as compile time tags for algorithm selection. +They are: +\tcode{output_iterator_tag}, +\tcode{input_iterator_tag}, +\tcode{forward_iterator_tag}, +\tcode{bidirectional_iterator_tag}, +\tcode{random_access_iterator_tag}, +and +\tcode{contiguous_iterator_tag}. +For every iterator of type +\tcode{I}, +\tcode{iterator_traits::it\-er\-a\-tor_ca\-te\-go\-ry} +shall be defined to be a category tag that describes the +iterator's behavior. +Additionally, +\tcode{iterator_traits::it\-er\-a\-tor_con\-cept} +may be used to indicate conformance to +the iterator concepts\iref{iterator.concepts}. + +\begin{codeblock} +namespace std { + struct output_iterator_tag { }; + struct input_iterator_tag { }; + struct forward_iterator_tag: public input_iterator_tag { }; + struct bidirectional_iterator_tag: public forward_iterator_tag { }; + struct random_access_iterator_tag: public bidirectional_iterator_tag { }; + struct contiguous_iterator_tag: public random_access_iterator_tag { }; +} +\end{codeblock} + +\pnum +\begin{example} +For a program-defined iterator +\tcode{BinaryTreeIterator}, +it could be included +into the bidirectional iterator category by specializing the +\tcode{iterator_traits} +template: + +\begin{codeblock} +template struct iterator_traits> { + using iterator_category = bidirectional_iterator_tag; + using difference_type = ptrdiff_t; + using value_type = T; + using pointer = T*; + using reference = T&; +}; +\end{codeblock} +\end{example} + +\pnum +\begin{example} +If +\tcode{evolve()} +is well-defined for bidirectional iterators, but can be implemented more +efficiently for random access iterators, then the implementation is as follows: + +\begin{codeblock} +template +inline void +evolve(BidirectionalIterator first, BidirectionalIterator last) { + evolve(first, last, + typename iterator_traits::iterator_category()); +} + +template +void evolve(BidirectionalIterator first, BidirectionalIterator last, + bidirectional_iterator_tag) { + // more generic, but less efficient algorithm +} + +template +void evolve(RandomAccessIterator first, RandomAccessIterator last, + random_access_iterator_tag) { + // more efficient, but less generic algorithm +} +\end{codeblock} +\end{example} + +\rSec2[iterator.operations]{Iterator operations} + +\pnum +Since only random access iterators provide +\tcode{+} +and +\tcode{-} +operators, the library provides two +function templates +\tcode{advance} +and +\tcode{distance}. +These +function templates +use +\tcode{+} +and +\tcode{-} +for random access iterators (and are, therefore, constant +time for them); for input, forward and bidirectional iterators they use +\tcode{++} +to provide linear time +implementations. + +\indexlibrary{\idxcode{advance}}% +\begin{itemdecl} +template + constexpr void advance(InputIterator& i, Distance n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{n} +is negative only for bidirectional iterators. + +\pnum +\effects +Increments \tcode{i} by \tcode{n} if \tcode{n} is non-negative, and +decrements \tcode{i} by \tcode{-n} otherwise. +\end{itemdescr} + +\indexlibrary{\idxcode{distance}}% +\begin{itemdecl} +template + constexpr typename iterator_traits::difference_type + distance(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{last} is reachable from \tcode{first}, or +\tcode{InputIterator} meets +the \oldconcept{RandomAccessIterator} requirements and +\tcode{first} is reachable from \tcode{last}. + +\pnum +\effects +If \tcode{InputIterator} meets the \oldconcept{RandomAccessIterator} requirements, +returns \tcode{(last - first)}; otherwise, returns +the number of increments needed to get from +\tcode{first} +to +\tcode{last}. +\end{itemdescr} + +\indexlibrary{\idxcode{next}}% +\begin{itemdecl} +template + constexpr InputIterator next(InputIterator x, + typename iterator_traits::difference_type n = 1); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{advance(x, n); return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{prev}}% +\begin{itemdecl} +template + constexpr BidirectionalIterator prev(BidirectionalIterator x, + typename iterator_traits::difference_type n = 1); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{advance(x, -n); return x;} +\end{itemdescr} + +\rSec2[range.iter.ops]{Range iterator operations} + +\pnum +The library includes the function templates +\tcode{ranges::advance}, \tcode{ranges::distance}, +\tcode{ranges::next}, and \tcode{ranges::prev} +to manipulate iterators. These operations adapt to the set of operators +provided by each iterator category to provide the most efficient implementation +possible for a concrete iterator type. +\begin{example} +\tcode{ranges::advance} uses the \tcode{+} operator to move a +\libconcept{RandomAccessIterator} forward \tcode{n} steps in constant time. +For an iterator type that does not model \libconcept{RandomAccessIterator}, +\tcode{ranges::advance} instead performs \tcode{n} individual increments with +the \tcode{++} operator. +\end{example} + +\pnum +The function templates defined in this subclause are not found by +argument-dependent name lookup\iref{basic.lookup.argdep}. When found by +unqualified\iref{basic.lookup.unqual} name lookup for the +\grammarterm{postfix-expression} in a function call\iref{expr.call}, they +inhibit argument-dependent name lookup. + +\begin{example} +\begin{codeblock} +void foo() { + using namespace std::ranges; + std::vector vec{1,2,3}; + distance(begin(vec), end(vec)); // \#1 +} +\end{codeblock} +The function call expression at \tcode{\#1} invokes \tcode{std::ranges::distance}, +not \tcode{std::distance}, despite that +(a) the iterator type returned from \tcode{begin(vec)} and \tcode{end(vec)} +may be associated with namespace \tcode{std} and +(b) \tcode{std::distance} is more specialized~(\ref{temp.func.order}) than +\tcode{std::ranges::distance} since the former requires its first two parameters +to have the same type. +\end{example} + +\pnum +The number and order of deducible template parameters for the function templates defined +in this subclause is unspecified, except where explicitly stated otherwise. + +\rSec3[range.iter.op.advance]{\tcode{ranges::advance}} + +\indexlibrary{\idxcode{advance}}% +\begin{itemdecl} +template + constexpr void advance(I& i, iter_difference_t n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{I} does not model \libconcept{BidirectionalIterator}, +\tcode{n} is not negative. + +\pnum +\effects +\begin{itemize} +\item If \tcode{I} models \libconcept{RandomAccessIterator}, + equivalent to \tcode{i += n}. +\item Otherwise, if \tcode{n} is non-negative, increments + \tcode{i} by \tcode{n}. +\item Otherwise, decrements \tcode{i} by \tcode{-n}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{advance}}% +\begin{itemdecl} +template S> + constexpr void advance(I& i, S bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{i}{bound} denotes a range. + +\pnum +\effects +\begin{itemize} +\item If \tcode{I} and \tcode{S} model \tcode{Assignable}, + equivalent to \tcode{i = std::move(bound)}. +\item Otherwise, if \tcode{S} and \tcode{I} model \tcode{SizedSentinel}, + equivalent to \tcode{ranges::advance(i, bound - i)}. +\item Otherwise, while \tcode{bool(i != bound)} is \tcode{true}, + increments \tcode{i}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{advance}}% +\begin{itemdecl} +template S> + constexpr iter_difference_t advance(I& i, iter_difference_t n, S bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{n > 0}, \range{i}{bound} denotes a range. +If \tcode{n == 0}, \range{i}{bound} or \range{bound}{i} denotes a range. +If \tcode{n < 0}, \range{bound}{i} denotes a range, +\tcode{I} models \libconcept{BidirectionalIterator}, and +\tcode{I} and \tcode{S} model \tcode{Same}. + +\pnum +\effects +\begin{itemize} +\item If \tcode{S} and \tcode{I} model \tcode{SizedSentinel}: + \begin{itemize} + \item If \brk{}$|\tcode{n}| \ge |\tcode{bound - i}|$, + equivalent to \tcode{ranges::advance(i, bound)}. + \item Otherwise, equivalent to \tcode{ranges::advance(i, n)}. + \end{itemize} +\item Otherwise, + \begin{itemize} + \item if \tcode{n} is non-negative, + while \tcode{bool(i != bound)} is \tcode{true}, + increments \tcode{i} but at most \tcode{n} times. + \item Otherwise, + while \tcode{bool(i != bound)} is \tcode{true}, + decrements \tcode{i} but at most \tcode{-n} times. + \end{itemize} +\end{itemize} + +\pnum +\returns +\tcode{n - $M$}, where $M$ is the difference between +the ending and starting positions of \tcode{i}. +\end{itemdescr} + +\rSec3[range.iter.op.distance]{\tcode{ranges::distance}} +\indexlibrary{\idxcode{distance}}% +\begin{itemdecl} +template S> + constexpr iter_difference_t distance(I first, S last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{first}{last} denotes a range, or +\range{last}{first} denotes a range and +\tcode{S} and \tcode{I} model +\tcode{Same \&\& SizedSentinel}. + +\pnum +\effects +If \tcode{S} and \tcode{I} model \tcode{SizedSentinel}, +returns \tcode{(last - first)}; +otherwise, returns the number of increments needed to get from +\tcode{first} +to +\tcode{last}. +\end{itemdescr} + +\indexlibrary{\idxcode{distance}}% +\begin{itemdecl} +template + constexpr iter_difference_t> distance(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{R} models \libconcept{SizedRange}, equivalent to: +\begin{codeblock} +return ranges::size(r); // \ref{range.prim.size} +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +return ranges::distance(ranges::begin(r), ranges::end(r)); // \ref{range.access} +\end{codeblock} +\end{itemdescr} + +\rSec3[range.iter.op.next]{\tcode{ranges::next}} + +\indexlibrary{\idxcode{next}}% +\begin{itemdecl} +template + constexpr I next(I x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{++x; return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{next}}% +\begin{itemdecl} +template + constexpr I next(I x, iter_difference_t n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{ranges::advance(x, n); return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{next}}% +\begin{itemdecl} +template S> + constexpr I next(I x, S bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{ranges::advance(x, bound); return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{next}}% +\begin{itemdecl} +template S> + constexpr I next(I x, iter_difference_t n, S bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{ranges::advance(x, n, bound); return x;} +\end{itemdescr} + +\rSec3[range.iter.op.prev]{\tcode{ranges::prev}} +\indexlibrary{\idxcode{prev}}% +\begin{itemdecl} +template + constexpr I prev(I x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{-{-}x; return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{prev}}% +\begin{itemdecl} +template + constexpr I prev(I x, iter_difference_t n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{ranges::advance(x, -n); return x;} +\end{itemdescr} + +\indexlibrary{\idxcode{prev}}% +\begin{itemdecl} +template + constexpr I prev(I x, iter_difference_t n, I bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{ranges::advance(x, -n, bound); return x;} +\end{itemdescr} + +\rSec1[predef.iterators]{Iterator adaptors} + +\rSec2[reverse.iterators]{Reverse iterators} + +\pnum +Class template \tcode{reverse_iterator} is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence. + +\rSec3[reverse.iterator]{Class template \tcode{reverse_iterator}} + +\indexlibrary{\idxcode{reverse_iterator}}% +\begin{codeblock} +namespace std { + template + class reverse_iterator { + public: + using iterator_type = Iterator; + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; + using value_type = iter_value_t; + using difference_type = iter_difference_t; + using pointer = typename iterator_traits::pointer; + using reference = iter_reference_t; + + constexpr reverse_iterator(); + constexpr explicit reverse_iterator(Iterator x); + template constexpr reverse_iterator(const reverse_iterator& u); + template constexpr reverse_iterator& operator=(const reverse_iterator& u); + + constexpr Iterator base() const; + constexpr reference operator*() const; + constexpr pointer operator->() const requires @\seebelow@; + + constexpr reverse_iterator& operator++(); + constexpr reverse_iterator operator++(int); + constexpr reverse_iterator& operator--(); + constexpr reverse_iterator operator--(int); + + constexpr reverse_iterator operator+ (difference_type n) const; + constexpr reverse_iterator& operator+=(difference_type n); + constexpr reverse_iterator operator- (difference_type n) const; + constexpr reverse_iterator& operator-=(difference_type n); + constexpr @\unspec@ operator[](difference_type n) const; + + friend constexpr iter_rvalue_reference_t + iter_move(const reverse_iterator& i) noexcept(@\seebelow@); + template Iterator2> + friend constexpr void + iter_swap(const reverse_iterator\& x, + const reverse_iterator\& y) noexcept(@\seebelow@); + + protected: + Iterator current; + }; + + template + constexpr bool operator==( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator!=( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator<( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator>( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator<=( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr bool operator>=( + const reverse_iterator& x, + const reverse_iterator& y); + template + constexpr auto operator-( + const reverse_iterator& x, + const reverse_iterator& y) -> decltype(y.base() - x.base()); + template + constexpr reverse_iterator operator+( + typename reverse_iterator::difference_type n, + const reverse_iterator& x); + + template + constexpr reverse_iterator make_reverse_iterator(Iterator i); + + template + requires (!SizedSentinel) + inline constexpr bool disable_sized_sentinel, + reverse_iterator> = true; +} +\end{codeblock} + +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_concept} denotes +\begin{itemize} +\item +\tcode{random_access_iterator_tag} if \tcode{Iterator} models +\libconcept{RandomAccessIterator}, and +\item +\tcode{bidirectional_iterator_tag} otherwise. +\end{itemize} + +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} denotes +\begin{itemize} +\item +\tcode{random_access_iterator_tag} if +the type +\tcode{iterator_traits<\brk{}Iterator>::iterator_category} models +\libconcept{DerivedFrom}, and +\item +\tcode{iterator_traits<\brk{}Iterator>::iterator_category} otherwise. +\end{itemize} + +\rSec3[reverse.iter.requirements]{Requirements} + +\pnum +The template parameter +\tcode{Iterator} +shall either meet the requirements of a +\oldconcept{BidirectionalIterator}\iref{bidirectional.iterators} +or model +\libconcept{BidirectionalIterator}\iref{iterator.concept.bidir}. + +\pnum +Additionally, +\tcode{Iterator} +shall either meet the requirements of a +\oldconcept{RandomAccessIterator}\iref{random.access.iterators} +or model +\libconcept{RandomAccessIterator}\iref{iterator.concept.random.access} +if the definitions of any of the members +\begin{itemize} +\item +\tcode{operator+}, +\tcode{operator-}, +\tcode{operator+=}, +\tcode{operator-=}\iref{reverse.iter.nav}, or +\item +\tcode{operator[]}\iref{reverse.iter.elem}, +\end{itemize} +or the non-member operators\iref{reverse.iter.cmp} +\begin{itemize} +\item +\tcode{operator<}, +\tcode{operator>}, +\tcode{operator<=}, +\tcode{operator>=}, +\tcode{operator-}, +or +\tcode{operator+}\iref{reverse.iter.nonmember} +\end{itemize} +are instantiated\iref{temp.inst}. + +\rSec3[reverse.iter.cons]{Construction and assignment} + +\indexlibrary{\idxcode{reverse_iterator}!constructor}% +\begin{itemdecl} +constexpr reverse_iterator(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Value-initializes +\tcode{current}. +Iterator operations applied to the resulting iterator have defined behavior +if and only if the corresponding operations are defined on a value-initialized iterator of type +\tcode{Iterator}. +\end{itemdescr} + +\indexlibrary{\idxcode{reverse_iterator}!constructor}% +\begin{itemdecl} +constexpr explicit reverse_iterator(Iterator x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{current} +with \tcode{x}. +\end{itemdescr} + +\indexlibrary{\idxcode{reverse_iterator}!constructor}% +\begin{itemdecl} +template constexpr reverse_iterator(const reverse_iterator& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{current} +with +\tcode{u.current}. +\end{itemdescr} + +\indexlibrarymember{operator=}{reverse_iterator}% +\begin{itemdecl} +template +constexpr reverse_iterator& + operator=(const reverse_iterator& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Assigns \tcode{u.base()} to current. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\rSec3[reverse.iter.conv]{Conversion} + +\indexlibrarymember{base}{reverse_iterator}% +\begin{itemdecl} +constexpr Iterator base() const; // explicit +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{current}. +\end{itemdescr} + +\rSec3[reverse.iter.elem]{Element access} + +\indexlibrarymember{operator*}{reverse_iterator}% +\begin{itemdecl} +constexpr reference operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +Iterator tmp = current; +return *--tmp; +\end{codeblock} + +\end{itemdescr} + +\indexlibrarymember{operator->}{reverse_iterator}% +\begin{itemdecl} +constexpr pointer operator->() const + requires (is_pointer_v || + requires (const Iterator i) { i.operator->(); }); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\begin{itemize} +\item If \tcode{Iterator} is a pointer type, equivalent to: +\tcode{return prev(current);} + +\item Otherwise, equivalent to: +\tcode{return prev(current).operator->();} +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{operator[]}{reverse_iterator}% +\begin{itemdecl} +constexpr @\unspec@ operator[](difference_type n) const; +\end{itemdecl} - // \ref{predef.iterators}, predefined iterators - template class reverse_iterator; +\begin{itemdescr} +\pnum +\returns +\tcode{current[-n-1]}. +\end{itemdescr} - template - constexpr bool operator==( - const reverse_iterator& x, - const reverse_iterator& y); - template - constexpr bool operator!=( - const reverse_iterator& x, - const reverse_iterator& y); - template - constexpr bool operator<( - const reverse_iterator& x, - const reverse_iterator& y); - template - constexpr bool operator>( - const reverse_iterator& x, - const reverse_iterator& y); - template - constexpr bool operator<=( - const reverse_iterator& x, - const reverse_iterator& y); - template - constexpr bool operator>=( - const reverse_iterator& x, - const reverse_iterator& y); +\rSec3[reverse.iter.nav]{Navigation} + +\indexlibrarymember{operator+}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator operator+(difference_type n) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator(current-n)}. +\end{itemdescr} + +\indexlibrarymember{operator-}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator operator-(difference_type n) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator(current+n)}. +\end{itemdescr} + +\indexlibrarymember{operator++}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: \tcode{\dcr current;} + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +reverse_iterator tmp = *this; +--current; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator& operator--(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by \tcode{++current}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator operator--(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +reverse_iterator tmp = *this; +++current; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+=}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator& operator+=(difference_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: \tcode{current -= n;} + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{reverse_iterator}% +\begin{itemdecl} +constexpr reverse_iterator& operator-=(difference_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: \tcode{current += n;} + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\rSec3[reverse.iter.cmp]{Comparisons} + +\indexlibrarymember{operator==}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator==( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current == y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current == y.current}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator!=( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current != y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current != y.current}. +\end{itemdescr} + +\indexlibrarymember{operator<}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator<( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current > y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current > y.current}. +\end{itemdescr} + +\indexlibrarymember{operator>}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator>( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current < y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current < y.current}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator<=( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current >= y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current >= y.current}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{reverse_iterator}% +\begin{itemdecl} +template + constexpr bool operator>=( + const reverse_iterator& x, + const reverse_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.current <= y.current} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.current <= y.current}. +\end{itemdescr} + +\rSec3[reverse.iter.nonmember]{Non-member functions} + +\indexlibrarymember{operator-}{reverse_iterator}% +\begin{itemdecl} +template + constexpr auto operator-( + const reverse_iterator& x, + const reverse_iterator& y) -> decltype(y.base() - x.base()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{y.current - x.current}. +\end{itemdescr} - template - constexpr auto operator-( - const reverse_iterator& x, - const reverse_iterator& y) -> decltype(y.base() - x.base()); - template - constexpr reverse_iterator - operator+( +\indexlibrarymember{operator+}{reverse_iterator}% +\begin{itemdecl} +template + constexpr reverse_iterator operator+( typename reverse_iterator::difference_type n, const reverse_iterator& x); +\end{itemdecl} - template - constexpr reverse_iterator make_reverse_iterator(Iterator i); +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator (x.current - n)}. +\end{itemdescr} - template class back_insert_iterator; - template - back_insert_iterator back_inserter(Container& x); +\indexlibrarymember{iter_move}{reverse_iterator}% +\begin{itemdecl} +friend constexpr iter_rvalue_reference_t + iter_move(const reverse_iterator& i) noexcept(@\seebelow@); +\end{itemdecl} - template class front_insert_iterator; - template - front_insert_iterator front_inserter(Container& x); +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = i.current; +return ranges::iter_move(--tmp); +\end{codeblock} - template class insert_iterator; - template - insert_iterator inserter(Container& x, typename Container::iterator i); +\pnum +\remarks The expression in \tcode{noexcept} is equivalent to: +\begin{codeblock} +is_nothrow_copy_constructible_v && +noexcept(ranges::iter_move(--declval())) +\end{codeblock} +\end{itemdescr} - template class move_iterator; - template - constexpr bool operator==( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator!=( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator<( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator>( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator<=( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator>=( - const move_iterator& x, const move_iterator& y); +\indexlibrarymember{iter_swap}{reverse_iterator}% +\begin{itemdecl} +template Iterator2> + friend constexpr void + iter_swap(const reverse_iterator& x, + const reverse_iterator& y) noexcept(@\seebelow@); +\end{itemdecl} - template - constexpr auto operator-( - const move_iterator& x, - const move_iterator& y) -> decltype(x.base() - y.base()); - template - constexpr move_iterator operator+( - typename move_iterator::difference_type n, const move_iterator& x); - template - constexpr move_iterator make_move_iterator(Iterator i); +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto xtmp = x.current; +auto ytmp = y.current; +ranges::iter_swap(--xtmp, --ytmp); +\end{codeblock} - // \ref{stream.iterators}, stream iterators - template, - class Distance = ptrdiff_t> - class istream_iterator; - template - bool operator==(const istream_iterator& x, - const istream_iterator& y); - template - bool operator!=(const istream_iterator& x, - const istream_iterator& y); +\pnum +\remarks The expression in \tcode{noexcept} is equivalent to: +\begin{codeblock} +is_nothrow_copy_constructible_v && +is_nothrow_copy_constructible_v && +noexcept(ranges::iter_swap(--declval(), --declval())) +\end{codeblock} +\end{itemdescr} - template> - class ostream_iterator; +\indexlibrary{\idxcode{reverse_iterator}!\idxcode{make_reverse_iterator} non-member function}% +\indexlibrary{\idxcode{make_reverse_iterator}}% +\begin{itemdecl} +template + constexpr reverse_iterator make_reverse_iterator(Iterator i); +\end{itemdecl} - template> - class istreambuf_iterator; - template - bool operator==(const istreambuf_iterator& a, - const istreambuf_iterator& b); - template - bool operator!=(const istreambuf_iterator& a, - const istreambuf_iterator& b); +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator(i)}. +\end{itemdescr} - template> - class ostreambuf_iterator; +\rSec2[insert.iterators]{Insert iterators} - // \ref{iterator.range}, range access - template constexpr auto begin(C& c) -> decltype(c.begin()); - template constexpr auto begin(const C& c) -> decltype(c.begin()); - template constexpr auto end(C& c) -> decltype(c.end()); - template constexpr auto end(const C& c) -> decltype(c.end()); - template constexpr T* begin(T (&array)[N]) noexcept; - template constexpr T* end(T (&array)[N]) noexcept; - template constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) - -> decltype(std::begin(c)); - template constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) - -> decltype(std::end(c)); - template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); - template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); - template constexpr auto rend(C& c) -> decltype(c.rend()); - template constexpr auto rend(const C& c) -> decltype(c.rend()); - template constexpr reverse_iterator rbegin(T (&array)[N]); - template constexpr reverse_iterator rend(T (&array)[N]); - template constexpr reverse_iterator rbegin(initializer_list il); - template constexpr reverse_iterator rend(initializer_list il); - template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); - template constexpr auto crend(const C& c) -> decltype(std::rend(c)); +\pnum +To make it possible to deal with insertion in the same way as writing into an array, a special kind of iterator +adaptors, called +\term{insert iterators}, +are provided in the library. +With regular iterator classes, - // \ref{iterator.container}, container access - template constexpr auto size(const C& c) -> decltype(c.size()); - template constexpr size_t size(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; - template constexpr auto data(C& c) -> decltype(c.data()); - template constexpr auto data(const C& c) -> decltype(c.data()); - template constexpr T* data(T (&array)[N]) noexcept; - template constexpr const E* data(initializer_list il) noexcept; +\begin{codeblock} +while (first != last) *result++ = *first++; +\end{codeblock} + +causes a range \range{first}{last} +to be copied into a range starting with result. +The same code with +\tcode{result} +being an insert iterator will insert corresponding elements into the container. +This device allows all of the +copying algorithms in the library to work in the +\term{insert mode} +instead of the \term{regular overwrite} mode. + +\pnum +An insert iterator is constructed from a container and possibly one of its iterators pointing to where +insertion takes place if it is neither at the beginning nor at the end of the container. +Insert iterators satisfy the requirements of output iterators. +\tcode{operator*} +returns the insert iterator itself. +The assignment +\tcode{operator=(const T\& x)} +is defined on insert iterators to allow writing into them, it inserts +\tcode{x} +right before where the insert iterator is pointing. +In other words, an insert iterator is like a cursor pointing into the +container where the insertion takes place. +\tcode{back_insert_iterator} +inserts elements at the end of a container, +\tcode{front_insert_iterator} +inserts elements at the beginning of a container, and +\tcode{insert_iterator} +inserts elements where the iterator points to in a container. +\tcode{back_inserter}, +\tcode{front_inserter}, +and +\tcode{inserter} +are three +functions making the insert iterators out of a container. + +\rSec3[back.insert.iterator]{Class template \tcode{back_insert_iterator}} + +\indexlibrary{\idxcode{back_insert_iterator}}% +\begin{codeblock} +namespace std { + template + class back_insert_iterator { + protected: + Container* container = nullptr; + + public: + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = ptrdiff_t; + using pointer = void; + using reference = void; + using container_type = Container; + + constexpr back_insert_iterator() noexcept = default; + constexpr explicit back_insert_iterator(Container& x); + constexpr back_insert_iterator& operator=(const typename Container::value_type& value); + constexpr back_insert_iterator& operator=(typename Container::value_type&& value); + + constexpr back_insert_iterator& operator*(); + constexpr back_insert_iterator& operator++(); + constexpr back_insert_iterator operator++(int); + }; + + template + constexpr back_insert_iterator back_inserter(Container& x); } \end{codeblock} -\rSec1[iterator.primitives]{Iterator primitives} +\rSec4[back.insert.iter.ops]{Operations} + +\indexlibrary{\idxcode{back_insert_iterator}!constructor}% +\begin{itemdecl} +constexpr explicit back_insert_iterator(Container& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{container} +with \tcode{addressof(x)}. +\end{itemdescr} + +\indexlibrarymember{operator=}{back_insert_iterator}% +\begin{itemdecl} +constexpr back_insert_iterator& operator=(const typename Container::value_type& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: \tcode{container->push_back(value);} + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{back_insert_iterator}% +\begin{itemdecl} +constexpr back_insert_iterator& operator=(typename Container::value_type&& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: \tcode{container->push_back(std::move(value));} + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator*}{back_insert_iterator}% +\begin{itemdecl} +constexpr back_insert_iterator& operator*(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{back_insert_iterator}% +\begin{itemdecl} +constexpr back_insert_iterator& operator++(); +constexpr back_insert_iterator operator++(int); +\end{itemdecl} +\begin{itemdescr} \pnum -To simplify the task of defining iterators, the library provides -several classes and functions: +\returns +\tcode{*this}. +\end{itemdescr} -\rSec2[iterator.traits]{Iterator traits} +\rSec4[back.inserter]{ \tcode{back_inserter}} + +\indexlibrary{\idxcode{back_inserter}}% +\begin{itemdecl} +template + constexpr back_insert_iterator back_inserter(Container& x); +\end{itemdecl} +\begin{itemdescr} \pnum -\indexlibrary{\idxcode{iterator_traits}}% -To implement algorithms only in terms of iterators, it is often necessary to -determine the value and -difference types that correspond to a particular iterator type. -Accordingly, it is required that if -\tcode{Iterator} -is the type of an iterator, -the types +\returns +\tcode{back_insert_iterator(x)}. +\end{itemdescr} -\indexlibrarymember{difference_type}{iterator_traits}% -\indexlibrarymember{value_type}{iterator_traits}% -\indexlibrarymember{iterator_category}{iterator_traits}% +\rSec3[front.insert.iterator]{Class template \tcode{front_insert_iterator}} + +\indexlibrary{\idxcode{front_insert_iterator}}% \begin{codeblock} -iterator_traits::difference_type -iterator_traits::value_type -iterator_traits::iterator_category -\end{codeblock} +namespace std { + template + class front_insert_iterator { + protected: + Container* container = nullptr; -be defined as the iterator's difference type, value type and iterator category, respectively. -In addition, the types + public: + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = ptrdiff_t; + using pointer = void; + using reference = void; + using container_type = Container; -\indexlibrarymember{reference}{iterator_traits}% -\indexlibrarymember{pointer}{iterator_traits}% -\begin{codeblock} -iterator_traits::reference -iterator_traits::pointer -\end{codeblock} + constexpr front_insert_iterator(Container& x) noexcept = default; + constexpr explicit front_insert_iterator(Container& x); + constexpr front_insert_iterator& operator=(const typename Container::value_type& value); + constexpr front_insert_iterator& operator=(typename Container::value_type&& value); -shall be defined as the iterator's reference and pointer types, that is, for an -iterator object \tcode{a}, the same type as the type of \tcode{*a} and \tcode{a->}, -respectively. In the case of an output iterator, the types + constexpr front_insert_iterator& operator*(); + constexpr front_insert_iterator& operator++(); + constexpr front_insert_iterator operator++(int); + }; -\begin{codeblock} -iterator_traits::difference_type -iterator_traits::value_type -iterator_traits::reference -iterator_traits::pointer + template + constexpr front_insert_iterator front_inserter(Container& x); +} \end{codeblock} -may be defined as \tcode{void}. +\rSec4[front.insert.iter.ops]{Operations} + +\indexlibrary{\idxcode{front_insert_iterator}!constructor}% +\begin{itemdecl} +constexpr explicit front_insert_iterator(Container& x); +\end{itemdecl} +\begin{itemdescr} \pnum -If \tcode{Iterator} has valid\iref{temp.deduct} member -types \tcode{difference_type}, \tcode{value_type}, \tcode{pointer}, -\tcode{reference}, and \tcode{iterator_category}, -\tcode{iterator_traits} -shall have the following as publicly accessible members: -\begin{codeblock} - using difference_type = typename Iterator::difference_type; - using value_type = typename Iterator::value_type; - using pointer = typename Iterator::pointer; - using reference = typename Iterator::reference; - using iterator_category = typename Iterator::iterator_category; -\end{codeblock} -Otherwise, \tcode{iterator_traits} -shall have no members by any of the above names. +\effects +Initializes +\tcode{container} +with \tcode{addressof(x)}. +\end{itemdescr} + +\indexlibrarymember{operator=}{front_insert_iterator}% +\begin{itemdecl} +constexpr front_insert_iterator& operator=(const typename Container::value_type& value); +\end{itemdecl} +\begin{itemdescr} \pnum -It is specialized for pointers as +\effects +As if by: \tcode{container->push_front(value);} -\begin{codeblock} -namespace std { - template struct iterator_traits { - using difference_type = ptrdiff_t; - using value_type = remove_cv_t; - using pointer = T*; - using reference = T&; - using iterator_category = random_access_iterator_tag; - }; -} -\end{codeblock} +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{front_insert_iterator}% +\begin{itemdecl} +constexpr front_insert_iterator& operator=(typename Container::value_type&& value); +\end{itemdecl} +\begin{itemdescr} \pnum -\begin{example} -To implement a generic -\tcode{reverse} -function, a \Cpp{} program can do the following: +\effects +As if by: \tcode{container->push_front(std::move(value));} -\begin{codeblock} -template -void reverse(BidirectionalIterator first, BidirectionalIterator last) { - typename iterator_traits::difference_type n = - distance(first, last); - --n; - while(n > 0) { - typename iterator_traits::value_type - tmp = *first; - *first++ = *--last; - *last = tmp; - n -= 2; - } -} -\end{codeblock} -\end{example} +\pnum +\returns +\tcode{*this}. +\end{itemdescr} -\rSec2[std.iterator.tags]{Standard iterator tags} +\indexlibrarymember{operator*}{front_insert_iterator}% +\begin{itemdecl} +constexpr front_insert_iterator& operator*(); +\end{itemdecl} +\begin{itemdescr} \pnum -\indexlibrary{\idxcode{input_iterator_tag}}% -\indexlibrary{\idxcode{output_iterator_tag}}% -\indexlibrary{\idxcode{forward_iterator_tag}}% -\indexlibrary{\idxcode{bidirectional_iterator_tag}}% -\indexlibrary{\idxcode{random_access_iterator_tag}}% -It is often desirable for a -function template specialization -to find out what is the most specific category of its iterator -argument, so that the function can select the most efficient algorithm at compile time. -To facilitate this, the -library introduces -\term{category tag} -classes which are used as compile time tags for algorithm selection. -They are: -\tcode{input_iterator_tag}, -\tcode{output_iterator_tag}, -\tcode{forward_iterator_tag}, -\tcode{bidirectional_iterator_tag} -and -\tcode{random_access_iterator_tag}. -For every iterator of type -\tcode{Iterator}, -\tcode{iterator_traits::it\-er\-a\-tor_ca\-te\-go\-ry} -shall be defined to be the most specific category tag that describes the -iterator's behavior. +\returns +\tcode{*this}. +\end{itemdescr} -\begin{codeblock} -namespace std { - struct input_iterator_tag { }; - struct output_iterator_tag { }; - struct forward_iterator_tag: public input_iterator_tag { }; - struct bidirectional_iterator_tag: public forward_iterator_tag { }; - struct random_access_iterator_tag: public bidirectional_iterator_tag { }; -} -\end{codeblock} +\indexlibrarymember{operator++}{front_insert_iterator}% +\begin{itemdecl} +constexpr front_insert_iterator& operator++(); +constexpr front_insert_iterator operator++(int); +\end{itemdecl} +\begin{itemdescr} \pnum -\indexlibrary{\idxcode{empty}}% -\indexlibrary{\idxcode{input_iterator_tag}}% -\indexlibrary{\idxcode{output_iterator_tag}}% -\indexlibrary{\idxcode{forward_iterator_tag}}% -\indexlibrary{\idxcode{bidirectional_iterator_tag}}% -\indexlibrary{\idxcode{random_access_iterator_tag}}% -\begin{example} -For a program-defined iterator -\tcode{BinaryTreeIterator}, -it could be included -into the bidirectional iterator category by specializing the -\tcode{iterator_traits} -template: +\returns +\tcode{*this}. +\end{itemdescr} -\begin{codeblock} -template struct iterator_traits> { - using iterator_category = bidirectional_iterator_tag; - using difference_type = ptrdiff_t; - using value_type = T; - using pointer = T*; - using reference = T&; -}; -\end{codeblock} -\end{example} +\rSec4[front.inserter]{\tcode{front_inserter}} + +\indexlibrary{\idxcode{front_inserter}}% +\begin{itemdecl} +template + constexpr front_insert_iterator front_inserter(Container& x); +\end{itemdecl} +\begin{itemdescr} \pnum -\begin{example} -If -\tcode{evolve()} -is well-defined for bidirectional iterators, but can be implemented more -efficiently for random access iterators, then the implementation is as follows: +\returns +\tcode{front_insert_iterator(x)}. +\end{itemdescr} + +\rSec3[insert.iterator]{Class template \tcode{insert_iterator}} +\indexlibrary{\idxcode{insert_iterator}}% \begin{codeblock} -template -inline void -evolve(BidirectionalIterator first, BidirectionalIterator last) { - evolve(first, last, - typename iterator_traits::iterator_category()); -} +namespace std { + template + class insert_iterator { + protected: + Container* container = nullptr; + iterator_t iter = iterator_t(); -template -void evolve(BidirectionalIterator first, BidirectionalIterator last, - bidirectional_iterator_tag) { - // more generic, but less efficient algorithm -} + public: + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = ptrdiff_t; + using pointer = void; + using reference = void; + using container_type = Container; -template -void evolve(RandomAccessIterator first, RandomAccessIterator last, - random_access_iterator_tag) { - // more efficient, but less generic algorithm + insert_iterator() = default; + constexpr insert_iterator(Container& x, iterator_t i); + constexpr insert_iterator& operator=(const typename Container::value_type& value); + constexpr insert_iterator& operator=(typename Container::value_type&& value); + + constexpr insert_iterator& operator*(); + constexpr insert_iterator& operator++(); + constexpr insert_iterator& operator++(int); + }; + + template + constexpr insert_iterator + inserter(Container& x, iterator_t i); } \end{codeblock} -\end{example} -\rSec2[iterator.operations]{Iterator operations} +\rSec4[insert.iter.ops]{Operations} -\pnum -Since only random access iterators provide -\tcode{+} -and -\tcode{-} -operators, the library provides two -function templates -\tcode{advance} -and -\tcode{distance}. -These -function templates -use -\tcode{+} -and -\tcode{-} -for random access iterators (and are, therefore, constant -time for them); for input, forward and bidirectional iterators they use -\tcode{++} -to provide linear time -implementations. +\indexlibrary{\idxcode{insert_iterator}!constructor}% +\begin{itemdecl} +constexpr insert_iterator(Container& x, iterator_t i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{container} +with \tcode{addressof(x)} and +\tcode{iter} +with \tcode{i}. +\end{itemdescr} -\indexlibrary{\idxcode{advance}}% +\indexlibrarymember{operator=}{insert_iterator}% \begin{itemdecl} -template - constexpr void advance(InputIterator& i, Distance n); +constexpr insert_iterator& operator=(const typename Container::value_type& value); \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{n} -shall be negative only for bidirectional and random access iterators. +\effects +As if by: +\begin{codeblock} +iter = container->insert(iter, value); +++iter; +\end{codeblock} \pnum -\effects -Increments (or decrements for negative -\tcode{n}) -iterator reference -\tcode{i} -by -\tcode{n}. +\returns +\tcode{*this}. \end{itemdescr} -\indexlibrary{\idxcode{distance}}% +\indexlibrarymember{operator=}{insert_iterator}% \begin{itemdecl} -template - constexpr typename iterator_traits::difference_type - distance(InputIterator first, InputIterator last); +constexpr insert_iterator& operator=(typename Container::value_type&& value); \end{itemdecl} \begin{itemdescr} \pnum \effects -If \tcode{InputIterator} meets the \oldconcept{RandomAccessIterator} requirements, -returns \tcode{(last - first)}; otherwise, returns -the number of increments needed to get from -\tcode{first} -to -\tcode{last}. +As if by: +\begin{codeblock} +iter = container->insert(iter, std::move(value)); +++iter; +\end{codeblock} \pnum -\requires -If \tcode{InputIterator} meets the \oldconcept{RandomAccessIterator} requirements, -\tcode{last} shall be reachable from \tcode{first} or \tcode{first} shall be -reachable from \tcode{last}; otherwise, -\tcode{last} -shall be reachable from -\tcode{first}. +\returns +\tcode{*this}. \end{itemdescr} -\indexlibrary{\idxcode{next}}% +\indexlibrarymember{operator*}{insert_iterator}% \begin{itemdecl} -template - constexpr InputIterator next(InputIterator x, - typename iterator_traits::difference_type n = 1); +constexpr insert_iterator& operator*(); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{advance(x, n); return x;} +\returns +\tcode{*this}. \end{itemdescr} -\indexlibrary{\idxcode{prev}}% +\indexlibrarymember{operator++}{insert_iterator}% \begin{itemdecl} -template - constexpr BidirectionalIterator prev(BidirectionalIterator x, - typename iterator_traits::difference_type n = 1); +constexpr insert_iterator& operator++(); +constexpr insert_iterator& operator++(int); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{advance(x, -n); return x;} +\returns +\tcode{*this}. \end{itemdescr} -\rSec1[predef.iterators]{Iterator adaptors} +\rSec4[inserter]{\tcode{inserter}} -\rSec2[reverse.iterators]{Reverse iterators} +\indexlibrary{\idxcode{inserter}}% +\begin{itemdecl} +template + constexpr insert_iterator + inserter(Container& x, iterator_t i); +\end{itemdecl} +\begin{itemdescr} \pnum -Class template \tcode{reverse_iterator} is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence. -The fundamental relation between a reverse iterator and its corresponding iterator -\tcode{i} -is established by the identity: -\tcode{\&*(reverse_iterator(i)) == \&*(i - 1)}. +\returns +\tcode{insert_iterator(x, i)}. +\end{itemdescr} -\rSec3[reverse.iterator]{Class template \tcode{reverse_iterator}} +\rSec2[move.iterators]{Move iterators and sentinels} -\indexlibrary{\idxcode{reverse_iterator}}% +\pnum +Class template \tcode{move_iterator} is an iterator adaptor +with the same behavior as the underlying iterator except that its +indirection operator implicitly converts the value returned by the +underlying iterator's indirection operator to an rvalue. +Some generic algorithms can be called with move iterators to replace +copying with moving. + +\pnum +\begin{example} + +\begin{codeblock} +list s; +// populate the list \tcode{s} +vector v1(s.begin(), s.end()); // copies strings into \tcode{v1} +vector v2(make_move_iterator(s.begin()), + make_move_iterator(s.end())); // moves strings into \tcode{v2} +\end{codeblock} + +\end{example} + +\rSec3[move.iterator]{Class template \tcode{move_iterator}} + +\indexlibrary{\idxcode{move_iterator}}% \begin{codeblock} namespace std { template - class reverse_iterator { + class move_iterator { public: using iterator_type = Iterator; - using iterator_category = typename iterator_traits::iterator_category; - using value_type = typename iterator_traits::value_type; - using difference_type = typename iterator_traits::difference_type; - using pointer = typename iterator_traits::pointer; - using reference = typename iterator_traits::reference; + using iterator_concept = input_iterator_tag; + using iterator_category = @\seebelow@; + using value_type = iter_value_t; + using difference_type = iter_difference_t; + using pointer = Iterator; + using reference = iter_rvalue_reference_t; - constexpr reverse_iterator(); - constexpr explicit reverse_iterator(Iterator x); - template constexpr reverse_iterator(const reverse_iterator& u); - template constexpr reverse_iterator& operator=(const reverse_iterator& u); + constexpr move_iterator(); + constexpr explicit move_iterator(Iterator i); + template constexpr move_iterator(const move_iterator& u); + template constexpr move_iterator& operator=(const move_iterator& u); - constexpr Iterator base() const; // explicit + constexpr iterator_type base() const; constexpr reference operator*() const; - constexpr pointer operator->() const; + constexpr pointer operator->() const; - constexpr reverse_iterator& operator++(); - constexpr reverse_iterator operator++(int); - constexpr reverse_iterator& operator--(); - constexpr reverse_iterator operator--(int); + constexpr move_iterator& operator++(); + constexpr auto operator++(int); + constexpr move_iterator& operator--(); + constexpr move_iterator operator--(int); - constexpr reverse_iterator operator+ (difference_type n) const; - constexpr reverse_iterator& operator+=(difference_type n); - constexpr reverse_iterator operator- (difference_type n) const; - constexpr reverse_iterator& operator-=(difference_type n); - constexpr @\unspecnc@ operator[](difference_type n) const; + constexpr move_iterator operator+(difference_type n) const; + constexpr move_iterator& operator+=(difference_type n); + constexpr move_iterator operator-(difference_type n) const; + constexpr move_iterator& operator-=(difference_type n); + constexpr reference operator[](difference_type n) const; + + template S> + friend constexpr bool + operator==(const move_iterator& x, const move_sentinel& y); + template S> + friend constexpr bool + operator==(const move_sentinel& x, const move_iterator& y); + template S> + friend constexpr bool + operator!=(const move_iterator& x, const move_sentinel& y); + template S> + friend constexpr bool + operator!=(const move_sentinel& x, const move_iterator& y); + template S> + friend constexpr iter_difference_t + operator-(const move_sentinel& x, const move_iterator& y); + template S> + friend constexpr iter_difference_t + operator-(const move_iterator& x, const move_sentinel& y); + friend constexpr iter_rvalue_reference_t + iter_move(const move_iterator& i) + noexcept(noexcept(ranges::iter_move(i.current))); + template Iterator2> + friend constexpr void + iter_swap(const move_iterator& x, const move_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current, y.current))); - protected: - Iterator current; + private: + Iterator current; // \expos }; template constexpr bool operator==( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); template constexpr bool operator!=( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); template constexpr bool operator<( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); template constexpr bool operator>( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); template constexpr bool operator<=( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); template constexpr bool operator>=( - const reverse_iterator& x, - const reverse_iterator& y); + const move_iterator& x, const move_iterator& y); + template - constexpr auto operator-( - const reverse_iterator& x, - const reverse_iterator& y) -> decltype(y.base() - x.base()); + constexpr auto operator-(const move_iterator& x, + const move_iterator& y) + -> decltype(x.base() - y.base()); template - constexpr reverse_iterator operator+( - typename reverse_iterator::difference_type n, - const reverse_iterator& x); - + constexpr move_iterator + operator+(iter_difference_t n, const move_iterator& x); template - constexpr reverse_iterator make_reverse_iterator(Iterator i); + constexpr move_iterator make_move_iterator(Iterator i); } \end{codeblock} -\rSec3[reverse.iter.requirements]{\tcode{reverse_iterator} requirements} - \pnum -The template parameter -\tcode{Iterator} -shall satisfy all the requirements of a \oldconcept{BidirectionalIterator}\iref{bidirectional.iterators}. +The member \grammarterm{typedef-name} \tcode{iterator_category} denotes +\begin{itemize} +\item +\tcode{random_access_iterator_tag} if +the type +\tcode{iterator_traits<\brk{}Iterator>::iterator_category} models +\libconcept{DerivedFrom<\tcode{random_access_iterator_tag}>}, and +\item +\tcode{iterator_traits<\brk{}Iterator>::iterator_category} otherwise. +\end{itemize} + +\rSec3[move.iter.requirements]{Requirements} \pnum -Additionally, -\tcode{Iterator} -shall satisfy the requirements of a \oldconcept{RandomAccessIterator}\iref{random.access.iterators} -if any of the members -\tcode{operator+}, -\tcode{operator-}, -\tcode{operator+=}, -\tcode{operator-=}\iref{reverse.iter.nav}, -\tcode{operator[]}\iref{reverse.iter.elem}, -or the non-member operators\iref{reverse.iter.cmp} -\tcode{operator<}, -\tcode{operator>}, -\tcode{operator<=}, -\tcode{operator>=}, -\tcode{operator-}, -or -\tcode{operator+}\iref{reverse.iter.nonmember} -are referenced in a way that requires instantiation\iref{temp.inst}. +The template parameter \tcode{Iterator} shall either +meet the \oldconcept{InputIterator} requirements\iref{input.iterators} +or model \libconcept{InputIterator}\iref{iterator.concept.input}. +Additionally, if any of the bidirectional traversal +functions are instantiated, the template parameter shall either +meet the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} +or model \libconcept{BidirectionalIterator}\iref{iterator.concept.bidir}. +If any of the random access traversal functions are instantiated, the +template parameter shall either +meet the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} +or model +\libconcept{RandomAccess\-Iterator}\iref{iterator.concept.random.access}. -\rSec3[reverse.iter.cons]{\tcode{reverse_iterator} construction and assignment} +\rSec3[move.iter.cons]{Construction and assignment} -\indexlibrary{\idxcode{reverse_iterator}!constructor}% +\indexlibrary{\idxcode{move_iterator}!constructor}% \begin{itemdecl} -constexpr reverse_iterator(); +constexpr move_iterator(); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Value-initializes -\tcode{current}. -Iterator operations applied to the resulting iterator have defined behavior -if and only if the corresponding operations are defined on a value-initialized iterator of type -\tcode{Iterator}. +\effects Constructs a \tcode{move_iterator}, value-initializing +\tcode{current}. Iterator operations applied to the resulting +iterator have defined behavior if and only if the corresponding operations are defined +on a value-initialized iterator of type \tcode{Iterator}. \end{itemdescr} -\indexlibrary{\idxcode{reverse_iterator}!constructor}% + +\indexlibrary{\idxcode{move_iterator}!constructor}% \begin{itemdecl} -constexpr explicit reverse_iterator(Iterator x); +constexpr explicit move_iterator(Iterator i); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Initializes -\tcode{current} -with \tcode{x}. +\effects Constructs a \tcode{move_iterator}, initializing +\tcode{current} with \tcode{i}. \end{itemdescr} -\indexlibrary{\idxcode{reverse_iterator}!constructor}% + +\indexlibrary{\idxcode{move_iterator}!constructor}% \begin{itemdecl} -template constexpr reverse_iterator(const reverse_iterator& u); +template constexpr move_iterator(const move_iterator& u); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Initializes -\tcode{current} -with -\tcode{u.current}. +\effects Constructs a \tcode{move_iterator}, initializing +\tcode{current} with \tcode{u.base()}. + +\pnum +\requires \tcode{U} shall be convertible to +\tcode{Iterator}. \end{itemdescr} -\indexlibrarymember{operator=}{reverse_iterator}% +\indexlibrarymember{operator=}{move_iterator}% \begin{itemdecl} -template -constexpr reverse_iterator& - operator=(const reverse_iterator& u); +template constexpr move_iterator& operator=(const move_iterator& u); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Assigns \tcode{u.base()} to current. +\effects Assigns \tcode{u.base()} to +\tcode{current}. \pnum -\returns -\tcode{*this}. +\requires \tcode{U} shall be convertible to +\tcode{Iterator}. \end{itemdescr} -\rSec3[reverse.iter.conv]{Conversion} +\rSec3[move.iter.op.conv]{Conversion} -\indexlibrarymember{base}{reverse_iterator}% +\indexlibrarymember{base}{move_iterator}% \begin{itemdecl} -constexpr Iterator base() const; // explicit +constexpr Iterator base() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{current}. +\returns \tcode{current}. \end{itemdescr} -\rSec3[reverse.iter.elem]{\tcode{reverse_iterator} element access} +\rSec3[move.iter.elem]{Element access} -\indexlibrarymember{operator*}{reverse_iterator}% +\indexlibrarymember{operator*}{move_iterator}% \begin{itemdecl} -constexpr reference operator*() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -As if by: -\begin{codeblock} -Iterator tmp = current; -return *--tmp; -\end{codeblock} +constexpr reference operator*() const; +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return ranges::iter_move(current);} \end{itemdescr} -\indexlibrarymember{operator->}{reverse_iterator}% +\indexlibrarymember{operator->}{move_iterator}% \begin{itemdecl} constexpr pointer operator->() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{addressof(operator*())}. +\returns \tcode{current}. \end{itemdescr} -\indexlibrarymember{operator[]}{reverse_iterator}% +\indexlibrarymember{operator[]}{move_iterator}% \begin{itemdecl} -constexpr @\unspec@ operator[](difference_type n) const; +constexpr reference operator[](difference_type n) const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{current[-n-1]}. +\effects Equivalent to: \tcode{ranges::iter_move(current + n);} \end{itemdescr} -\rSec3[reverse.iter.nav]{\tcode{reverse_iterator} navigation} +\rSec3[move.iter.nav]{Navigation} -\indexlibrarymember{operator+}{reverse_iterator}% +\indexlibrarymember{operator++}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator operator+(difference_type n) const; +constexpr move_iterator& operator++(); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{reverse_iterator(current-n)}. +\effects As if by \tcode{++current}. + +\pnum +\returns \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator-}{reverse_iterator}% +\indexlibrarymember{operator++}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator operator-(difference_type n) const; +constexpr auto operator++(int); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{reverse_iterator(current+n)}. +\effects +If \tcode{Iterator} models \libconcept{ForwardIterator}, equivalent to: +\begin{codeblock} +move_iterator tmp = *this; +++current; +return tmp; +\end{codeblock} +Otherwise, equivalent to \tcode{++current}. \end{itemdescr} -\indexlibrarymember{operator++}{reverse_iterator}% +\indexlibrarymember{operator\dcr}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator& operator++(); +constexpr move_iterator& operator--(); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{\dcr current;} +\effects As if by \tcode{\dcr current}. \pnum -\returns -\tcode{*this}. +\returns \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator++}{reverse_iterator}% +\indexlibrarymember{operator\dcr}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator operator++(int); +constexpr move_iterator operator--(int); \end{itemdecl} \begin{itemdescr} @@ -1443,1027 +4210,1413 @@ \effects As if by: \begin{codeblock} -reverse_iterator tmp = *this; +move_iterator tmp = *this; --current; return tmp; \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator\dcr}{reverse_iterator}% +\indexlibrarymember{operator+}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator& operator--(); +constexpr move_iterator operator+(difference_type n) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by \tcode{++current}. - -\pnum -\returns -\tcode{*this}. +\returns \tcode{move_iterator(current + n)}. \end{itemdescr} -\indexlibrarymember{operator\dcr}{reverse_iterator}% +\indexlibrarymember{operator+=}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator operator--(int); +constexpr move_iterator& operator+=(difference_type n); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: -\begin{codeblock} -reverse_iterator tmp = *this; -++current; -return tmp; -\end{codeblock} +\effects As if by: \tcode{current += n;} + +\pnum +\returns \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator+=}{reverse_iterator}% +\indexlibrarymember{operator-}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator& operator+=(difference_type n); +constexpr move_iterator operator-(difference_type n) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{current -= n;} - -\pnum -\returns -\tcode{*this}. +\returns \tcode{move_iterator(current - n)}. \end{itemdescr} -\indexlibrarymember{operator-=}{reverse_iterator}% +\indexlibrarymember{operator-=}{move_iterator}% \begin{itemdecl} -constexpr reverse_iterator& operator-=(difference_type n); +constexpr move_iterator& operator-=(difference_type n); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{current += n;} +\effects As if by: \tcode{current -= n;} \pnum -\returns -\tcode{*this}. +\returns \tcode{*this}. \end{itemdescr} -\rSec3[reverse.iter.cmp]{\tcode{reverse_iterator} comparisons} +\rSec3[move.iter.op.comp]{Comparisons} -\indexlibrarymember{operator==}{reverse_iterator}% +\indexlibrarymember{operator==}{move_iterator}% \begin{itemdecl} template - constexpr bool operator==( - const reverse_iterator& x, - const reverse_iterator& y); + constexpr bool operator==(const move_iterator& x, + const move_iterator& y); +template S> + friend constexpr bool operator==(const move_iterator& x, + const move_sentinel& y); +template S> + friend constexpr bool operator==(const move_sentinel& x, + const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current == y.current}. +\constraints +The expression \tcode{x.base() == y.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{x.base() == y.base()}. \end{itemdescr} -\indexlibrarymember{operator"!=}{reverse_iterator}% +\indexlibrarymember{operator"!=}{move_iterator}% \begin{itemdecl} template - constexpr bool operator!=( - const reverse_iterator& x, - const reverse_iterator& y); + constexpr bool operator!=(const move_iterator& x, + const move_iterator& y); +template S> + friend constexpr bool operator!=(const move_iterator& x, + const move_sentinel& y); +template S> + friend constexpr bool operator!=(const move_sentinel& x, + const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current != y.current}. +\constraints +The expression \tcode{x.base() == y.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{!(x == y)}. \end{itemdescr} -\indexlibrarymember{operator<}{reverse_iterator}% +\indexlibrarymember{operator<}{move_iterator}% \begin{itemdecl} template - constexpr bool operator<( - const reverse_iterator& x, - const reverse_iterator& y); +constexpr bool operator<(const move_iterator& x, const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current > y.current}. +\constraints +The expression \tcode{x.base() < y.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{x.base() < y.base()}. \end{itemdescr} -\indexlibrarymember{operator>}{reverse_iterator}% +\indexlibrarymember{operator>}{move_iterator}% \begin{itemdecl} template - constexpr bool operator>( - const reverse_iterator& x, - const reverse_iterator& y); +constexpr bool operator>(const move_iterator& x, const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current < y.current}. +\constraints +The expression \tcode{y.base() < x.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{y < x}. \end{itemdescr} -\indexlibrarymember{operator<=}{reverse_iterator}% +\indexlibrarymember{operator<=}{move_iterator}% \begin{itemdecl} template - constexpr bool operator<=( - const reverse_iterator& x, - const reverse_iterator& y); +constexpr bool operator<=(const move_iterator& x, const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current >= y.current}. +\constraints +The expression \tcode{y.base() < x.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{!(y < x)}. \end{itemdescr} -\indexlibrarymember{operator>=}{reverse_iterator}% +\indexlibrarymember{operator>=}{move_iterator}% \begin{itemdecl} template - constexpr bool operator>=( - const reverse_iterator& x, - const reverse_iterator& y); +constexpr bool operator>=(const move_iterator& x, const move_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.current <= y.current}. +\constraints +The expression \tcode{x.base() < y.base()} shall be valid and +convertible to \tcode{bool}. + +\pnum +\returns \tcode{!(x < y)}. \end{itemdescr} -\rSec3[reverse.iter.nonmember]{Non-member functions} +\rSec3[move.iter.nonmember]{Non-member functions} -\indexlibrarymember{operator-}{reverse_iterator}% +\indexlibrarymember{operator-}{move_iterator}% \begin{itemdecl} template - constexpr auto operator-( - const reverse_iterator& x, - const reverse_iterator& y) -> decltype(y.base() - x.base()); + constexpr auto operator-(const move_iterator& x, + const move_iterator& y) + -> decltype(x.base() - y.base()); +template S> + friend constexpr iter_difference_t + operator-(const move_sentinel& x, const move_iterator& y); +template S> + friend constexpr iter_difference_t + operator-(const move_iterator& x, const move_sentinel& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{y.current - x.current}. +\returns \tcode{x.base() - y.base()}. \end{itemdescr} -\indexlibrarymember{operator+}{reverse_iterator}% +\indexlibrarymember{operator+}{move_iterator}% \begin{itemdecl} template - constexpr reverse_iterator operator+( - typename reverse_iterator::difference_type n, - const reverse_iterator& x); + constexpr move_iterator + operator+(iter_difference_t n, const move_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{reverse_iterator (x.current - n)}. +\constraints +The expression \tcode{x + n} shall be valid and have type \tcode{Iterator}. + +\pnum +\returns \tcode{x + n}. \end{itemdescr} -\indexlibrary{\idxcode{reverse_iterator}!\idxcode{make_reverse_iterator} non-member function}% -\indexlibrary{\idxcode{make_reverse_iterator}}% +\indexlibrarymember{iter_move}{move_iterator}% \begin{itemdecl} -template - constexpr reverse_iterator make_reverse_iterator(Iterator i); +friend constexpr iter_rvalue_reference_t + iter_move(const move_iterator& i) + noexcept(noexcept(ranges::iter_move(i.current))); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{reverse_iterator(i)}. +\effects Equivalent to: \tcode{return ranges::iter_move(i.current);} \end{itemdescr} -\rSec2[insert.iterators]{Insert iterators} +\indexlibrarymember{iter_swap}{move_iterator}% +\begin{itemdecl} +template Iterator2> + friend constexpr void + iter_swap(const move_iterator& x, const move_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current, y.current))); +\end{itemdecl} +\begin{itemdescr} \pnum -To make it possible to deal with insertion in the same way as writing into an array, a special kind of iterator -adaptors, called -\term{insert iterators}, -are provided in the library. -With regular iterator classes, - -\begin{codeblock} -while (first != last) *result++ = *first++; -\end{codeblock} +\effects Equivalent to: \tcode{ranges::iter_swap(x.current, y.current)}. +\end{itemdescr} -causes a range \range{first}{last} -to be copied into a range starting with result. -The same code with -\tcode{result} -being an insert iterator will insert corresponding elements into the container. -This device allows all of the -copying algorithms in the library to work in the -\term{insert mode} -instead of the \term{regular overwrite} mode. +\indexlibrary{\idxcode{make_move_iterator}}% +\begin{itemdecl} +template +constexpr move_iterator make_move_iterator(Iterator i); +\end{itemdecl} +\begin{itemdescr} \pnum -An insert iterator is constructed from a container and possibly one of its iterators pointing to where -insertion takes place if it is neither at the beginning nor at the end of the container. -Insert iterators satisfy the requirements of output iterators. -\tcode{operator*} -returns the insert iterator itself. -The assignment -\tcode{operator=(const T\& x)} -is defined on insert iterators to allow writing into them, it inserts -\tcode{x} -right before where the insert iterator is pointing. -In other words, an insert iterator is like a cursor pointing into the -container where the insertion takes place. -\tcode{back_insert_iterator} -inserts elements at the end of a container, -\tcode{front_insert_iterator} -inserts elements at the beginning of a container, and -\tcode{insert_iterator} -inserts elements where the iterator points to in a container. -\tcode{back_inserter}, -\tcode{front_inserter}, -and -\tcode{inserter} -are three -functions making the insert iterators out of a container. +\returns \tcode{move_iterator(i)}. +\end{itemdescr} -\rSec3[back.insert.iterator]{Class template \tcode{back_insert_iterator}} +\rSec3[move.sentinel]{Class template \tcode{move_sentinel}} -\indexlibrary{\idxcode{back_insert_iterator}}% -\begin{codeblock} -namespace std { - template - class back_insert_iterator { - protected: - Container* container; +\pnum +Class template \tcode{move_sentinel} is a sentinel adaptor useful for denoting +ranges together with \tcode{move_iterator}. When an input iterator type +\tcode{I} and sentinel type \tcode{S} model \tcode{Sentinel}, +\tcode{move_sentinel} and \tcode{move_iterator} model +\tcode{Sentinel, move_iterator{>}} as well. - public: - using iterator_category = output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - using container_type = Container; +\pnum +\begin{example} +A \tcode{move_if} algorithm is easily implemented with +\tcode{copy_if} using \tcode{move_iterator} and \tcode{move_sentinel}: - explicit back_insert_iterator(Container& x); - back_insert_iterator& operator=(const typename Container::value_type& value); - back_insert_iterator& operator=(typename Container::value_type&& value); +\begin{codeblock} +template S, WeaklyIncrementable O, + IndirectUnaryPredicate Pred> + requires IndirectlyMovable +void move_if(I first, S last, O out, Pred pred) { + std::ranges::copy_if(move_iterator{first}, move_sentinel{last}, out, pred); +} +\end{codeblock} +\end{example} - back_insert_iterator& operator*(); - back_insert_iterator& operator++(); - back_insert_iterator operator++(int); +\indexlibrary{\idxcode{move_sentinel}}% +\begin{codeblock} +namespace std { + template + class move_sentinel { + public: + constexpr move_sentinel(); + constexpr explicit move_sentinel(S s); + template + requires ConvertibleTo + constexpr move_sentinel(const move_sentinel& s); + template + requires Assignable + constexpr move_sentinel& operator=(const move_sentinel& s); + + constexpr S base() const; + private: + S last; // \expos }; - - template - back_insert_iterator back_inserter(Container& x); } \end{codeblock} -\rSec4[back.insert.iter.ops]{\tcode{back_insert_iterator} operations} +\rSec3[move.sent.ops]{Operations} -\indexlibrary{\idxcode{back_insert_iterator}!constructor}% +\indexlibrary{\idxcode{move_sentinel}!constructor}% \begin{itemdecl} -explicit back_insert_iterator(Container& x); +constexpr move_sentinel(); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Initializes -\tcode{container} -with \tcode{addressof(x)}. +\effects Value-initializes \tcode{last}. +If \tcode{is_trivially_default_constructible_v} is \tcode{true}, +then this constructor is a \tcode{constexpr} constructor. \end{itemdescr} -\indexlibrarymember{operator=}{back_insert_iterator}% +\indexlibrary{\idxcode{move_sentinel}!constructor}% \begin{itemdecl} -back_insert_iterator& operator=(const typename Container::value_type& value); +constexpr explicit move_sentinel(S s); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{container->push_back(value);} - -\pnum -\returns -\tcode{*this}. +\effects Initializes \tcode{last} with \tcode{std::move(s)}. \end{itemdescr} -\indexlibrarymember{operator=}{back_insert_iterator}% +\indexlibrary{\idxcode{move_sentinel}!constructor}% \begin{itemdecl} -back_insert_iterator& operator=(typename Container::value_type&& value); +template + requires ConvertibleTo + constexpr move_sentinel(const move_sentinel& s); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{container->push_back(std::move(value));} - -\pnum -\returns -\tcode{*this}. +\effects Initializes \tcode{last} with \tcode{s.last}. \end{itemdescr} -\indexlibrarymember{operator*}{back_insert_iterator}% +\indexlibrary{\idxcode{operator=}!\idxcode{move_sentinel}}% +\indexlibrary{\idxcode{move_sentinel}!\idxcode{operator=}}% \begin{itemdecl} -back_insert_iterator& operator*(); +template + requires Assignable + constexpr move_sentinel& operator=(const move_sentinel& s); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{last = s.last; return *this;} \end{itemdescr} -\indexlibrarymember{operator++}{back_insert_iterator}% -\begin{itemdecl} -back_insert_iterator& operator++(); -back_insert_iterator operator++(int); -\end{itemdecl} +\rSec2[iterators.common]{Common iterators} -\begin{itemdescr} -\pnum -\returns -\tcode{*this}. -\end{itemdescr} +\rSec3[common.iterator]{Class template \tcode{common_iterator}} -\rSec4[back.inserter]{ \tcode{back_inserter}} +\pnum +Class template \tcode{common_iterator} is an iterator/sentinel adaptor that is +capable of representing a non-common range of elements (where the types of the +iterator and sentinel differ) as a common range (where they are the same). It +does this by holding either an iterator or a sentinel, and implementing the +equality comparison operators appropriately. -\indexlibrary{\idxcode{back_inserter}}% -\begin{itemdecl} -template - back_insert_iterator back_inserter(Container& x); -\end{itemdecl} +\pnum +\begin{note} +The \tcode{common_iterator} type is useful for interfacing with legacy +code that expects the begin and end of a range to have the same type. +\end{note} -\begin{itemdescr} \pnum -\returns -\tcode{back_insert_iterator(x)}. -\end{itemdescr} +\begin{example} +\begin{codeblock} +template +void fun(ForwardIterator begin, ForwardIterator end); -\rSec3[front.insert.iterator]{Class template \tcode{front_insert_iterator}} +list s; +// populate the list \tcode{s} +using CI = common_iterator::iterator>, default_sentinel_t>; +// call \tcode{fun} on a range of 10 ints +fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel)); +\end{codeblock} +\end{example} -\indexlibrary{\idxcode{front_insert_iterator}}% +\indexlibrary{\idxcode{common_iterator}}% \begin{codeblock} namespace std { - template - class front_insert_iterator { - protected: - Container* container; - + template S> + requires (!Same) + class common_iterator { public: - using iterator_category = output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - using container_type = Container; + constexpr common_iterator() = default; + constexpr common_iterator(I i); + constexpr common_iterator(S s); + template + requires ConvertibleTo && ConvertibleTo + constexpr common_iterator(const common_iterator& x); + + template + requires ConvertibleTo && ConvertibleTo && + Assignable && Assignable + common_iterator& operator=(const common_iterator& x); + + decltype(auto) operator*(); + decltype(auto) operator*() const + requires @\placeholder{dereferenceable}@; + decltype(auto) operator->() const + requires @\seebelow@; + + common_iterator& operator++(); + decltype(auto) operator++(int); + + template S2> + requires Sentinel + friend bool operator==( + const common_iterator& x, const common_iterator& y); + template S2> + requires Sentinel && EqualityComparableWith + friend bool operator==( + const common_iterator& x, const common_iterator& y); + template S2> + requires Sentinel + friend bool operator!=( + const common_iterator& x, const common_iterator& y); + + template I2, SizedSentinel S2> + requires SizedSentinel + friend iter_difference_t operator-( + const common_iterator& x, const common_iterator& y); + + friend iter_rvalue_reference_t iter_move(const common_iterator& i) + noexcept(noexcept(ranges::iter_move(declval()))) + requires InputIterator; + template I2, class S2> + friend void iter_swap(const common_iterator& x, const common_iterator& y) + noexcept(noexcept(ranges::iter_swap(declval(), declval()))); - explicit front_insert_iterator(Container& x); - front_insert_iterator& operator=(const typename Container::value_type& value); - front_insert_iterator& operator=(typename Container::value_type&& value); + private: + variant v_; // \expos + }; - front_insert_iterator& operator*(); - front_insert_iterator& operator++(); - front_insert_iterator operator++(int); + template + struct incrementable_traits> { + using difference_type = iter_difference_t; }; - template - front_insert_iterator front_inserter(Container& x); + template + struct iterator_traits> { + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; + using value_type = iter_value_t; + using difference_type = iter_difference_t; + using pointer = @\seebelow@; + using reference = iter_reference_t; + }; } \end{codeblock} -\rSec4[front.insert.iter.ops]{\tcode{front_insert_iterator} operations} +\rSec3[common.iter.types]{Associated types} -\indexlibrary{\idxcode{front_insert_iterator}!constructor}% +\pnum +The nested \grammarterm{typedef-name}s of the specialization of +\tcode{iterator_traits} for \tcode{common_iterator} are defined as follows. +\begin{itemize} +\item +\tcode{iterator_concept} denotes \tcode{forward_iterator_tag} +if \tcode{I} models \libconcept{ForwardIterator}; +otherwise it denotes \tcode{input_iterator_tag}. + +\item +\tcode{iterator_category} denotes +\tcode{forward_iterator_tag} +if \tcode{iterator_traits::iterator_category} +models \tcode{DerivedFrom}; +otherwise it denotes \tcode{input_iterator_tag}. + +\item +If the expression \tcode{a.operator->()} is well-formed, +where \tcode{a} is an lvalue of type \tcode{const common_iterator}, +then \tcode{pointer} denotes the type of that expression. +Otherwise, \tcode{pointer} denotes \tcode{void}. +\end{itemize} + +\rSec3[common.iter.const]{Constructors and conversions} + +\indexlibrary{\idxcode{common_iterator}!constructor}% \begin{itemdecl} -explicit front_insert_iterator(Container& x); +constexpr common_iterator(I i); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes -\tcode{container} -with \tcode{addressof(x)}. +Initializes \tcode{v_} as if by \tcode{v_\{in_place_type, std::move(i)\}}. \end{itemdescr} -\indexlibrarymember{operator=}{front_insert_iterator}% +\indexlibrary{\idxcode{common_iterator}!constructor}% \begin{itemdecl} -front_insert_iterator& operator=(const typename Container::value_type& value); +constexpr common_iterator(S s); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{container->push_front(value);} - -\pnum -\returns -\tcode{*this}. +\effects Initializes \tcode{v_} as if by +\tcode{v_\{in_place_type, std::move(s)\}}. \end{itemdescr} -\indexlibrarymember{operator=}{front_insert_iterator}% +\indexlibrary{\idxcode{common_iterator}!constructor}% \begin{itemdecl} -front_insert_iterator& operator=(typename Container::value_type&& value); +template + requires ConvertibleTo && ConvertibleTo + constexpr common_iterator(const common_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: \tcode{container->push_front(std::move(value));} +\expects \tcode{x.v_.valueless_by_exception()} is \tcode{false}. \pnum -\returns -\tcode{*this}. +\effects +Initializes \tcode{v_} as if by +\tcode{v_\{in_place_index<$i$>, get<$i$>(x.v_)\}}, +where $i$ is \tcode{x.v_.index()}. \end{itemdescr} -\indexlibrarymember{operator*}{front_insert_iterator}% +\indexlibrarymember{operator=}{common_iterator}% \begin{itemdecl} -front_insert_iterator& operator*(); +template + requires ConvertibleTo && ConvertibleTo && + Assignable && Assignable + common_iterator& operator=(const common_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{*this}. -\end{itemdescr} +\expects \tcode{x.v_.valueless_by_exception()} is \tcode{false}. -\indexlibrarymember{operator++}{front_insert_iterator}% -\begin{itemdecl} -front_insert_iterator& operator++(); -front_insert_iterator operator++(int); -\end{itemdecl} +\pnum +\effects +Equivalent to: +\begin{itemize} +\item If \tcode{v_.index() == x.v_.index()}, then +\tcode{get<$i$>(v_) = get<$i$>(x.v_)}. + +\item Otherwise, \tcode{v_.emplace<$i$>(get<$i$>(x.v_))}. +\end{itemize} +where $i$ is \tcode{x.v_.index()}. -\begin{itemdescr} \pnum -\returns -\tcode{*this}. +\returns \tcode{*this} \end{itemdescr} -\rSec4[front.inserter]{\tcode{front_inserter}} +\rSec3[common.iter.access]{Accessors} -\indexlibrary{\idxcode{front_inserter}}% +\indexlibrarymember{operator*}{common_iterator}% \begin{itemdecl} -template - front_insert_iterator front_inserter(Container& x); +decltype(auto) operator*(); +decltype(auto) operator*() const + requires @\placeholder{dereferenceable}@; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{front_insert_iterator(x)}. +\expects \tcode{holds_alternative(v_)}. + +\pnum +\effects Equivalent to: \tcode{return *get(v_);} \end{itemdescr} -\rSec3[insert.iterator]{Class template \tcode{insert_iterator}} +\indexlibrarymember{operator->}{common_iterator}% +\begin{itemdecl} +decltype(auto) operator->() const + requires @\seebelow@; +\end{itemdecl} -\indexlibrary{\idxcode{insert_iterator}}% +\begin{itemdescr} +\pnum +The expression in the requires clause is equivalent to: \begin{codeblock} -namespace std { - template - class insert_iterator { - protected: - Container* container; - typename Container::iterator iter; +Readable && +(requires(const I& i) { i.operator->(); } || + is_reference_v> || + Constructible, iter_reference_t>) +\end{codeblock} - public: - using iterator_category = output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - using container_type = Container; +\pnum +\expects \tcode{holds_alternative(v_)}. - insert_iterator(Container& x, typename Container::iterator i); - insert_iterator& operator=(const typename Container::value_type& value); - insert_iterator& operator=(typename Container::value_type&& value); +\pnum +\effects +\begin{itemize} +\item +If \tcode{I} is a pointer type or if the expression +\tcode{get(v_).operator->()} is +well-formed, equivalent to: \tcode{return get(v_);} - insert_iterator& operator*(); - insert_iterator& operator++(); - insert_iterator& operator++(int); - }; +\item +Otherwise, if \tcode{iter_reference_t} is a reference type, equivalent to: +\begin{codeblock} +auto&& tmp = *get(v_); +return addressof(tmp); +\end{codeblock} - template - insert_iterator inserter(Container& x, typename Container::iterator i); -} +\item +Otherwise, equivalent to: +\tcode{return \placeholder{proxy}(*get(v_));} where +\tcode{\placeholder{proxy}} is the exposition-only class: +\begin{codeblock} +class @\placeholder{proxy}@ { + iter_value_t keep_; + @\placeholder{proxy}@(iter_reference_t&& x) + : keep_(std::move(x)) {} +public: + const iter_value_t* operator->() const { + return addressof(keep_); + } +}; \end{codeblock} +\end{itemize} +\end{itemdescr} -\rSec4[insert.iter.ops]{\tcode{insert_iterator} operations} +\rSec3[common.iter.nav]{Navigation} -\indexlibrary{\idxcode{insert_iterator}!constructor}% +\indexlibrarymember{operator++}{common_iterator}% \begin{itemdecl} -insert_iterator(Container& x, typename Container::iterator i); +common_iterator& operator++(); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Initializes -\tcode{container} -with \tcode{addressof(x)} and -\tcode{iter} -with \tcode{i}. +\expects \tcode{holds_alternative(v_)}. + +\pnum +\effects Equivalent to \tcode{++get(v_)}. + +\pnum +\returns \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator=}{insert_iterator}% +\indexlibrarymember{operator++}{common_iterator}% \begin{itemdecl} -insert_iterator& operator=(const typename Container::value_type& value); +decltype(auto) operator++(int); \end{itemdecl} \begin{itemdescr} +\pnum +\expects \tcode{holds_alternative(v_)}. + \pnum \effects -As if by: +If \tcode{I} models \libconcept{ForwardIterator}, equivalent to: \begin{codeblock} -iter = container->insert(iter, value); -++iter; +common_iterator tmp = *this; +++*this; +return tmp; \end{codeblock} +Otherwise, equivalent to: \tcode{return get(v_)++;} +\end{itemdescr} + +\rSec3[common.iter.cmp]{Comparisons} + +\indexlibrarymember{operator==}{common_iterator}% +\begin{itemdecl} +template S2> + requires Sentinel +friend bool operator==( + const common_iterator& x, const common_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} +are each \tcode{false}. \pnum \returns -\tcode{*this}. +\tcode{true} if \tcode{$i$ == $j$}, +and otherwise \tcode{get<$i$>(x.v_) == get<$j$>(y.v_)}, +where $i$ is \tcode{x.v_.index()} and $j$ is \tcode{y.v_.index()}. \end{itemdescr} -\indexlibrarymember{operator=}{insert_iterator}% +\indexlibrarymember{operator==}{common_iterator}% \begin{itemdecl} -insert_iterator& operator=(typename Container::value_type&& value); +template S2> + requires Sentinel && EqualityComparableWith +friend bool operator==( + const common_iterator& x, const common_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: -\begin{codeblock} -iter = container->insert(iter, std::move(value)); -++iter; -\end{codeblock} +\expects +\tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} +are each \tcode{false}. \pnum \returns -\tcode{*this}. +\tcode{true} if $i$ and $j$ are each \tcode{1}, and otherwise +\tcode{get<$i$>(x.v_) == get<$j$>(y.v_)}, where +$i$ is \tcode{x.v_.index()} and $j$ is \tcode{y.v_.index()}. \end{itemdescr} -\indexlibrarymember{operator*}{insert_iterator}% +\indexlibrarymember{operator"!=}{common_iterator}% \begin{itemdecl} -insert_iterator& operator*(); +template S2> + requires Sentinel +friend bool operator!=( + const common_iterator& x, const common_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return !(x == y);} \end{itemdescr} -\indexlibrarymember{operator++}{insert_iterator}% +\indexlibrarymember{operator-}{common_iterator}% \begin{itemdecl} -insert_iterator& operator++(); -insert_iterator& operator++(int); +template I2, SizedSentinel S2> + requires SizedSentinel +friend iter_difference_t operator-( + const common_iterator& x, const common_iterator& y); \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} +are each \tcode{false}. + \pnum \returns -\tcode{*this}. +\tcode{0} if $i$ and $j$ are each \tcode{1}, and otherwise +\tcode{get<$i$>(x.v_) - get<$j$>(y.v_)}, where +$i$ is \tcode{x.v_.index()} and $j$ is \tcode{y.v_.index()}. \end{itemdescr} -\rSec4[inserter]{\tcode{inserter}} +\rSec3[common.iter.cust]{Customization} -\indexlibrary{\idxcode{inserter}}% +\indexlibrarymember{iter_move}{common_iterator}% \begin{itemdecl} -template - insert_iterator inserter(Container& x, typename Container::iterator i); +friend iter_rvalue_reference_t iter_move(const common_iterator& i) + noexcept(noexcept(ranges::iter_move(declval()))) + requires InputIterator; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{insert_iterator(x, i)}. +\expects \tcode{holds_alternative(v_)}. + +\pnum +\effects Equivalent to: \tcode{return ranges::iter_move(get(i.v_));} \end{itemdescr} -\rSec2[move.iterators]{Move iterators} +\indexlibrarymember{iter_swap}{common_iterator}% +\begin{itemdecl} +template I2, class S2> + friend void iter_swap(const common_iterator& x, const common_iterator& y) + noexcept(noexcept(ranges::iter_swap(declval(), declval()))); +\end{itemdecl} +\begin{itemdescr} \pnum -Class template \tcode{move_iterator} is an iterator adaptor -with the same behavior as the underlying iterator except that its -indirection operator implicitly converts the value returned by the -underlying iterator's indirection operator to an rvalue. -Some generic algorithms can be called with move iterators to replace -copying with moving. +\expects +\tcode{holds_alternative(x.v_)} and \tcode{holds_alternative(y.v_)} +are each \tcode{true}. \pnum -\begin{example} +\effects Equivalent to \tcode{ranges::iter_swap(get(x.v_), get(y.v_))}. +\end{itemdescr} + +\rSec2[default.sentinels]{Default sentinels} + +\indexlibrary{\idxcode{default_sentinel_t}}% +\begin{itemdecl} +namespace std { + struct default_sentinel_t { }; +} +\end{itemdecl} + +\pnum +Class \tcode{default_sentinel_t} is an empty type used to denote the end of a +range. It can be used together with iterator types that know the bound +of their range (e.g., \tcode{counted_iterator}\iref{counted.iterator}). + +\rSec2[iterators.counted]{Counted iterators} + +\rSec3[counted.iterator]{Class template \tcode{counted_iterator}} + +\pnum +Class template \tcode{counted_iterator} is an iterator adaptor +with the same behavior as the underlying iterator except that +it keeps track of the distance to the end of its range. +It can be used together with \tcode{default_sentinel} +in calls to generic algorithms to operate on +a range of $N$ elements starting at a given position +without needing to know the end position a priori. +\pnum +\begin{example} \begin{codeblock} list s; -// populate the list \tcode{s} -vector v1(s.begin(), s.end()); // copies strings into \tcode{v1} -vector v2(make_move_iterator(s.begin()), - make_move_iterator(s.end())); // moves strings into \tcode{v2} +// populate the list \tcode{s} with at least 10 strings +vector v; +// copies 10 strings into \tcode{v}: +ranges::copy(counted_iterator(s.begin(), 10), default_sentinel, back_inserter(v)); \end{codeblock} - \end{example} -\rSec3[move.iterator]{Class template \tcode{move_iterator}} +\pnum +Two values \tcode{i1} and \tcode{i2} of types +\tcode{counted_iterator} +and +\tcode{counted_iterator} +refer to elements of the same sequence if and only if +\tcode{next(i1.base(), i1.count())} +and +\tcode{next(i2.base(), i2.count())} +refer to the same (possibly past-the-end) element. -\indexlibrary{\idxcode{move_iterator}}% +\indexlibrary{\idxcode{counted_iterator}}% \begin{codeblock} namespace std { - template - class move_iterator { + template + class counted_iterator { public: - using iterator_type = Iterator; - using iterator_category = typename iterator_traits::iterator_category; - using value_type = typename iterator_traits::value_type; - using difference_type = typename iterator_traits::difference_type; - using pointer = Iterator; - using reference = @\seebelow@; - - constexpr move_iterator(); - constexpr explicit move_iterator(Iterator i); - template constexpr move_iterator(const move_iterator& u); - template constexpr move_iterator& operator=(const move_iterator& u); - - constexpr iterator_type base() const; - constexpr reference operator*() const; - constexpr pointer operator->() const; - - constexpr move_iterator& operator++(); - constexpr move_iterator operator++(int); - constexpr move_iterator& operator--(); - constexpr move_iterator operator--(int); - - constexpr move_iterator operator+(difference_type n) const; - constexpr move_iterator& operator+=(difference_type n); - constexpr move_iterator operator-(difference_type n) const; - constexpr move_iterator& operator-=(difference_type n); - constexpr @\unspec@ operator[](difference_type n) const; + using iterator_type = I; + + constexpr counted_iterator() = default; + constexpr counted_iterator(I x, iter_difference_t n); + template + requires ConvertibleTo + constexpr counted_iterator(const counted_iterator& x); + + template + requires Assignable + constexpr counted_iterator& operator=(const counted_iterator& x); + + constexpr I base() const; + constexpr iter_difference_t count() const noexcept; + constexpr decltype(auto) operator*(); + constexpr decltype(auto) operator*() const + requires @\placeholder{dereferenceable}@; + + constexpr counted_iterator& operator++(); + decltype(auto) operator++(int); + constexpr counted_iterator operator++(int) + requires ForwardIterator; + constexpr counted_iterator& operator--() + requires BidirectionalIterator; + constexpr counted_iterator operator--(int) + requires BidirectionalIterator; + + constexpr counted_iterator operator+(iter_difference_t n) const + requires RandomAccessIterator; + friend constexpr counted_iterator operator+( + iter_difference_t n, const counted_iterator& x) + requires RandomAccessIterator; + constexpr counted_iterator& operator+=(iter_difference_t n) + requires RandomAccessIterator; + + constexpr counted_iterator operator-(iter_difference_t n) const + requires RandomAccessIterator; + template I2> + friend constexpr iter_difference_t operator-( + const counted_iterator& x, const counted_iterator& y); + friend constexpr iter_difference_t operator-( + const counted_iterator& x, default_sentinel_t); + friend constexpr iter_difference_t operator-( + default_sentinel_t, const counted_iterator& y); + constexpr counted_iterator& operator-=(iter_difference_t n) + requires RandomAccessIterator; + + constexpr decltype(auto) operator[](iter_difference_t n) const + requires RandomAccessIterator; + + template I2> + friend constexpr bool operator==( + const counted_iterator& x, const counted_iterator& y); + friend constexpr bool operator==( + const counted_iterator& x, default_sentinel_t); + friend constexpr bool operator==( + default_sentinel_t, const counted_iterator& x); + + template I2> + friend constexpr bool operator!=( + const counted_iterator& x, const counted_iterator& y); + friend constexpr bool operator!=( + const counted_iterator& x, default_sentinel_t y); + friend constexpr bool operator!=( + default_sentinel_t x, const counted_iterator& y); + + template I2> + friend constexpr bool operator<( + const counted_iterator& x, const counted_iterator& y); + template I2> + friend constexpr bool operator>( + const counted_iterator& x, const counted_iterator& y); + template I2> + friend constexpr bool operator<=( + const counted_iterator& x, const counted_iterator& y); + template I2> + friend constexpr bool operator>=( + const counted_iterator& x, const counted_iterator& y); + + friend constexpr iter_rvalue_reference_t iter_move(const counted_iterator& i) + noexcept(noexcept(ranges::iter_move(i.current))) + requires InputIterator; + template I2> + friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current, y.current))); private: - Iterator current; // \expos + I current = I(); // \expos + iter_difference_t length = 0; // \expos }; - template - constexpr bool operator==( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator!=( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator<( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator>( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator<=( - const move_iterator& x, const move_iterator& y); - template - constexpr bool operator>=( - const move_iterator& x, const move_iterator& y); + template + struct incrementable_traits> { + using difference_type = iter_difference_t; + }; - template - constexpr auto operator-( - const move_iterator& x, - const move_iterator& y) -> decltype(x.base() - y.base()); - template - constexpr move_iterator operator+( - typename move_iterator::difference_type n, const move_iterator& x); - template - constexpr move_iterator make_move_iterator(Iterator i); + template + struct iterator_traits> : iterator_traits { + using pointer = void; + }; } \end{codeblock} -\pnum -Let \tcode{\placeholder{R}} denote \tcode{iterator_traits::reference}. -If \tcode{is_reference_v<\placeholder{R}>} is \tcode{true}, -the template specialization \tcode{move_iterator} shall define -the nested type named \tcode{reference} as a synonym for -\tcode{remove_reference_t<\placeholder{R}>\&\&}, -otherwise as a synonym for \tcode{\placeholder{R}}. +\rSec3[counted.iter.const]{Constructors and conversions} -\rSec3[move.iter.requirements]{\tcode{move_iterator} requirements} +\indexlibrary{\idxcode{counted_iterator}!constructor}% +\begin{itemdecl} +constexpr counted_iterator(I i, iter_difference_t n); +\end{itemdecl} +\begin{itemdescr} \pnum -The template parameter \tcode{Iterator} shall satisfy -the \oldconcept{InputIterator} requirements\iref{input.iterators}. -Additionally, if any of the bidirectional or random access traversal -functions are instantiated, the template parameter shall satisfy the -\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} -or \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}, respectively. +\expects \tcode{n >= 0}. -\rSec3[move.iter.cons]{\tcode{move_iterator} construction and assignment} +\pnum +\effects +Initializes \tcode{current} with \tcode{i} and +\tcode{length} with \tcode{n}. +\end{itemdescr} -\indexlibrary{\idxcode{move_iterator}!constructor}% +\indexlibrary{\idxcode{counted_iterator}!constructor}% \begin{itemdecl} -constexpr move_iterator(); +template + requires ConvertibleTo + constexpr counted_iterator(const counted_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{move_iterator}, value-initializing -\tcode{current}. Iterator operations applied to the resulting -iterator have defined behavior if and only if the corresponding operations are defined -on a value-initialized iterator of type \tcode{Iterator}. +\effects +Initializes \tcode{current} with \tcode{x.current} and +\tcode{length} with \tcode{x.length}. \end{itemdescr} - -\indexlibrary{\idxcode{move_iterator}!constructor}% +\indexlibrarymember{operator=}{counted_iterator}% \begin{itemdecl} -constexpr explicit move_iterator(Iterator i); +template + requires Assignable + constexpr counted_iterator& operator=(const counted_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{move_iterator}, initializing -\tcode{current} with \tcode{i}. +\effects +Assigns \tcode{x.current} to \tcode{current} and +\tcode{x.length} to \tcode{length}. + +\pnum +\returns \tcode{*this}. \end{itemdescr} +\rSec3[counted.iter.access]{Accessors} -\indexlibrary{\idxcode{move_iterator}!constructor}% +\indexlibrarymember{base}{counted_iterator}% \begin{itemdecl} -template constexpr move_iterator(const move_iterator& u); +constexpr I base() const; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{move_iterator}, initializing -\tcode{current} with \tcode{u.base()}. - -\pnum -\requires \tcode{U} shall be convertible to -\tcode{Iterator}. +\effects Equivalent to: \tcode{return current;} \end{itemdescr} -\indexlibrarymember{operator=}{move_iterator}% +\indexlibrarymember{count}{counted_iterator}% \begin{itemdecl} -template constexpr move_iterator& operator=(const move_iterator& u); +constexpr iter_difference_t count() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Assigns \tcode{u.base()} to -\tcode{current}. - -\pnum -\requires \tcode{U} shall be convertible to -\tcode{Iterator}. +\effects Equivalent to: \tcode{return length;} \end{itemdescr} -\rSec3[move.iter.op.conv]{\tcode{move_iterator} conversion} +\rSec3[counted.iter.elem]{Element access} -\indexlibrarymember{base}{move_iterator}% +\indexlibrarymember{operator*}{counted_iterator}% \begin{itemdecl} -constexpr Iterator base() const; +constexpr decltype(auto) operator*(); +constexpr decltype(auto) operator*() const + requires @\placeholder{dereferenceable}@; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{current}. +\effects Equivalent to: \tcode{return *current;} \end{itemdescr} -\rSec3[move.iter.elem]{\tcode{move_iterator} element access} - -\indexlibrarymember{operator*}{move_iterator}% +\indexlibrarymember{operator[]}{counted_iterator}% \begin{itemdecl} -constexpr reference operator*() const; +constexpr decltype(auto) operator[](iter_difference_t n) const + requires RandomAccessIterator; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{static_cast(*current)}. +\expects \tcode{n < length}. + +\pnum +\effects Equivalent to: \tcode{return current[n];} \end{itemdescr} -\indexlibrarymember{operator->}{move_iterator}% +\rSec3[counted.iter.nav]{Navigation} + +\indexlibrarymember{operator++}{counted_iterator}% \begin{itemdecl} -constexpr pointer operator->() const; +constexpr counted_iterator& operator++(); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{current}. +\expects \tcode{length > 0}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +++current; +--length; +return *this; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator[]}{move_iterator}% +\indexlibrarymember{operator++}{counted_iterator}% \begin{itemdecl} -constexpr @\unspec@ operator[](difference_type n) const; +decltype(auto) operator++(int); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{std::move(current[n])}. -\end{itemdescr} +\expects \tcode{length > 0}. -\rSec3[move.iter.nav]{\tcode{move_iterator} navigation} +\pnum +\effects Equivalent to: +\begin{codeblock} +--length; +try { return current++; } +catch(...) { ++length; throw; } +\end{codeblock} +\end{itemdescr} -\indexlibrarymember{operator++}{move_iterator}% +\indexlibrarymember{operator++}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator& operator++(); +constexpr counted_iterator operator++(int) + requires ForwardIterator; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{++current}. +\effects Equivalent to: +\begin{codeblock} +counted_iterator tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator{-}-}{counted_iterator}% +\begin{itemdecl} + constexpr counted_iterator& operator--(); + requires BidirectionalIterator +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{*this}. +\effects Equivalent to: +\begin{codeblock} +--current; +++length; +return *this; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator++}{move_iterator}% +\indexlibrarymember{operator{-}-}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator operator++(int); + constexpr counted_iterator operator--(int) + requires BidirectionalIterator; \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: +\effects Equivalent to: \begin{codeblock} -move_iterator tmp = *this; -++current; +counted_iterator tmp = *this; +--*this; return tmp; \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator\dcr}{move_iterator}% +\indexlibrarymember{operator+}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator& operator--(); + constexpr counted_iterator operator+(iter_difference_t n) const + requires RandomAccessIterator; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{\dcr current}. +\effects Equivalent to: \tcode{return counted_iterator(current + n, length - n);} +\end{itemdescr} + +\indexlibrarymember{operator+}{counted_iterator}% +\begin{itemdecl} +friend constexpr counted_iterator operator+( + iter_difference_t n, const counted_iterator& x) + requires RandomAccessIterator; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{*this}. +\effects Equivalent to: \tcode{return x + n;} \end{itemdescr} -\indexlibrarymember{operator\dcr}{move_iterator}% +\indexlibrarymember{operator+=}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator operator--(int); + constexpr counted_iterator& operator+=(iter_difference_t n) + requires RandomAccessIterator; \end{itemdecl} \begin{itemdescr} \pnum -\effects -As if by: +\expects \tcode{n <= length}. + +\pnum +\effects Equivalent to: \begin{codeblock} -move_iterator tmp = *this; ---current; -return tmp; +current += n; +length -= n; +return *this; \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator+}{move_iterator}% +\indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator operator+(difference_type n) const; + constexpr counted_iterator operator-(iter_difference_t n) const + requires RandomAccessIterator; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{move_iterator(current + n)}. +\effects Equivalent to: \tcode{return counted_iterator(current - n, length + n);} \end{itemdescr} -\indexlibrarymember{operator+=}{move_iterator}% +\indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator& operator+=(difference_type n); +template I2> + friend constexpr iter_difference_t operator-( + const counted_iterator& x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by: \tcode{current += n;} +\expects +\tcode{x} and \tcode{y} refer to elements of the same +sequence\iref{counted.iterator}. \pnum -\returns \tcode{*this}. +\effects Equivalent to: \tcode{return y.length - x.length;} \end{itemdescr} -\indexlibrarymember{operator-}{move_iterator}% +\indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator operator-(difference_type n) const; +friend constexpr iter_difference_t operator-( + const counted_iterator& x, default_sentinel_t); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{move_iterator(current - n)}. +\effects Equivalent to: +\tcode{return -x.length;} \end{itemdescr} -\indexlibrarymember{operator-=}{move_iterator}% +\indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} -constexpr move_iterator& operator-=(difference_type n); +friend constexpr iter_difference_t operator-( + default_sentinel_t, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by: \tcode{current -= n;} +\effects Equivalent to: \tcode{return y.length;} +\end{itemdescr} + +\indexlibrarymember{operator-=}{counted_iterator}% +\begin{itemdecl} +constexpr counted_iterator& operator-=(iter_difference_t n) + requires RandomAccessIterator; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{*this}. +\expects \tcode{-n <= length}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +current -= n; +length += n; +return *this; +\end{codeblock} \end{itemdescr} -\rSec3[move.iter.op.comp]{\tcode{move_iterator} comparisons} +\rSec3[counted.iter.cmp]{Comparisons} -\indexlibrarymember{operator==}{move_iterator}% +\indexlibrarymember{operator==}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator==(const move_iterator& x, const move_iterator& y); +template I2> + friend constexpr bool operator==( + const counted_iterator& x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{x.base() == y.base()}. +\expects +\tcode{x} and \tcode{y} refer to +elements of the same sequence\iref{counted.iterator}. + +\pnum +\effects Equivalent to: \tcode{return x.length == y.length;} \end{itemdescr} -\indexlibrarymember{operator"!=}{move_iterator}% +\indexlibrarymember{operator==}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator!=(const move_iterator& x, const move_iterator& y); +friend constexpr bool operator==( + const counted_iterator& x, default_sentinel_t); +friend constexpr bool operator==( + default_sentinel_t, const counted_iterator& x); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{!(x == y)}. +\effects Equivalent to: \tcode{return x.length == 0;} \end{itemdescr} -\indexlibrarymember{operator<}{move_iterator}% +\indexlibrarymember{operator"!=}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator<(const move_iterator& x, const move_iterator& y); +template I2> + friend constexpr bool operator!=( + const counted_iterator& x, const counted_iterator& y); +friend constexpr bool operator!=( + const counted_iterator& x, default_sentinel_t y); +friend constexpr bool operator!=( + default_sentinel_t x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{x.base() < y.base()}. +\effects Equivalent to: \tcode{return !(x == y);} \end{itemdescr} -\indexlibrarymember{operator>}{move_iterator}% +\indexlibrarymember{operator<}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator>(const move_iterator& x, const move_iterator& y); +template I2> + friend constexpr bool operator<( + const counted_iterator& x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{y < x}. +\expects +\tcode{x} and \tcode{y} refer to +elements of the same sequence\iref{counted.iterator}. + +\pnum +\effects Equivalent to: \tcode{return y.length < x.length;} + +\pnum +\begin{note} +The argument order in the \textit{Effects} element is reversed +because \tcode{length} counts down, not up. +\end{note} \end{itemdescr} -\indexlibrarymember{operator<=}{move_iterator}% +\indexlibrarymember{operator>}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator<=(const move_iterator& x, const move_iterator& y); +template I2> + friend constexpr bool operator>( + const counted_iterator& x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{!(y < x)}. +\effects Equivalent to: \tcode{return y < x;} \end{itemdescr} -\indexlibrarymember{operator>=}{move_iterator}% +\indexlibrarymember{operator<=}{counted_iterator}% \begin{itemdecl} -template -constexpr bool operator>=(const move_iterator& x, const move_iterator& y); +template I2> + friend constexpr bool operator<=( + const counted_iterator& x, const counted_iterator& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{!(x < y)}. +\effects Equivalent to: \tcode{return !(y < x);} \end{itemdescr} -\rSec3[move.iter.nonmember]{\tcode{move_iterator} non-member functions} +\indexlibrarymember{operator>=}{counted_iterator}% +\begin{itemdecl} +template I2> + friend constexpr bool operator>=( + const counted_iterator& x, const counted_iterator& y); +\end{itemdecl} -\indexlibrarymember{operator-}{move_iterator}% +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x < y);} +\end{itemdescr} + +\rSec3[counted.iter.cust]{Customizations} + +\indexlibrarymember{iter_move}{counted_iterator}% \begin{itemdecl} -template - constexpr auto operator-( - const move_iterator& x, - const move_iterator& y) -> decltype(x.base() - y.base()); +friend constexpr iter_rvalue_reference_t + iter_move(const counted_iterator& i) + noexcept(noexcept(ranges::iter_move(i.current))) + requires InputIterator; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{x.base() - y.base()}. +\effects Equivalent to: \tcode{return ranges::iter_move(i.current);} \end{itemdescr} -\indexlibrarymember{operator+}{move_iterator}% +\indexlibrarymember{iter_swap}{counted_iterator}% \begin{itemdecl} -template - constexpr move_iterator operator+( - typename move_iterator::difference_type n, const move_iterator& x); +template I2> + friend constexpr void + iter_swap(const counted_iterator& x, const counted_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current, y.current))); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{x + n}. +\effects Equivalent to \tcode{ranges::iter_swap(x.current, y.current)}. \end{itemdescr} -\indexlibrary{\idxcode{make_move_iterator}}% +\rSec2[unreachable.sentinels]{Unreachable sentinel} + +\rSec3[unreachable.sentinel]{Class \tcode{unreachable_sentinel_t}} + +\indexlibrary{\idxcode{unreachable_sentinel_t}}% +\indexlibrary{\idxcode{unreachable_sentinel}}% +\pnum +Class \tcode{unreachable_sentinel_t} can be used with +any \libconcept{WeaklyIncrementable} type +to denote the ``upper bound'' of an open interval. + +\pnum +\begin{example} +\begin{codeblock} +char* p; +// set \tcode{p} to point to a character buffer containing newlines +char* nl = find(p, unreachable_sentinel, '\n'); +\end{codeblock} + +Provided a newline character really exists in the buffer, the use of +\tcode{unreachable_sentinel} above potentially makes the call to \tcode{find} more +efficient since the loop test against the sentinel does not require a +conditional branch. +\end{example} + +\begin{codeblock} +namespace std { + struct unreachable_sentinel_t { + template + friend constexpr bool operator==(unreachable_sentinel_t, const I&) noexcept; + template + friend constexpr bool operator==(const I&, unreachable_sentinel_t) noexcept; + template + friend constexpr bool operator!=(unreachable_sentinel_t, const I&) noexcept; + template + friend constexpr bool operator!=(const I&, unreachable_sentinel_t) noexcept; + }; +} +\end{codeblock} + +\rSec3[unreachable.sentinel.cmp]{Comparisons} + +\indexlibrary{\idxcode{operator==}!\idxcode{unreachable_sentinel_t}}% +\indexlibrary{\idxcode{unreachable_sentinel_t}!\idxcode{operator==}}% \begin{itemdecl} -template -constexpr move_iterator make_move_iterator(Iterator i); +template + friend constexpr bool operator==(unreachable_sentinel_t, const I&) noexcept; +template + friend constexpr bool operator==(const I&, unreachable_sentinel_t) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{move_iterator(i)}. +\returns \tcode{false}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator"!=}!\idxcode{unreachable_sentinel_t}}% +\indexlibrary{\idxcode{unreachable_sentinel_t}!\idxcode{operator"!=}}% +\begin{itemdecl} +template + friend constexpr bool operator!=(unreachable_sentinel_t, const I&) noexcept; +template + friend constexpr bool operator!=(const I&, unreachable_sentinel_t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{true}. \end{itemdescr} \rSec1[stream.iterators]{Stream iterators} @@ -2553,6 +5706,7 @@ using istream_type = basic_istream; constexpr istream_iterator(); + constexpr istream_iterator(default_sentinel_t); istream_iterator(istream_type& s); istream_iterator(const istream_iterator& x) = default; ~istream_iterator() = default; @@ -2563,6 +5717,11 @@ istream_iterator& operator++(); istream_iterator operator++(int); + friend bool operator==(const istream_iterator& i, default_sentinel_t); + friend bool operator==(default_sentinel_t, const istream_iterator& i); + friend bool operator!=(const istream_iterator& x, default_sentinel_t y); + friend bool operator!=(default_sentinel_t x, const istream_iterator& y); + private: basic_istream* in_stream; // \expos T value; // \expos @@ -2577,12 +5736,12 @@ } \end{codeblock} -\rSec3[istream.iterator.cons]{\tcode{istream_iterator} constructors and destructor} - +\rSec3[istream.iterator.cons]{Constructors and destructor} \indexlibrary{\idxcode{istream_iterator}!constructor}% \begin{itemdecl} constexpr istream_iterator(); +constexpr istream_iterator(default_sentinel_t); \end{itemdecl} \begin{itemdescr} @@ -2590,10 +5749,10 @@ \effects Constructs the end-of-stream iterator. If \tcode{is_trivially_default_constructible_v} is \tcode{true}, -then this constructor is a constexpr constructor. +then these constructors are constexpr constructors. \pnum -\postconditions \tcode{in_stream == 0}. +\ensures \tcode{in_stream == 0}. \end{itemdescr} @@ -2610,7 +5769,7 @@ construction or the first time it is referenced. \pnum -\postconditions \tcode{in_stream == addressof(s)}. +\ensures \tcode{in_stream == addressof(s)}. \end{itemdescr} @@ -2627,7 +5786,7 @@ then this constructor is a trivial copy constructor. \pnum -\postconditions \tcode{in_stream == x.in_stream}. +\ensures \tcode{in_stream == x.in_stream}. \end{itemdescr} \indexlibrary{\idxcode{istream_iterator}!destructor}% @@ -2643,7 +5802,7 @@ then this destructor is trivial. \end{itemdescr} -\rSec3[istream.iterator.ops]{\tcode{istream_iterator} operations} +\rSec3[istream.iterator.ops]{Operations} \indexlibrarymember{operator*}{istream_iterator}% \begin{itemdecl} @@ -2714,7 +5873,19 @@ \begin{itemdescr} \pnum \returns -\tcode{x.in_stream == y.in_stream}.% +\tcode{x.in_stream == y.in_stream}. +\end{itemdescr} + +\indexlibrarymember{operator==}{istream_iterator}% +\begin{itemdecl} +friend bool operator==(default_sentinel_t, const istream_iterator& i); +friend bool operator==(const istream_iterator& i, default_sentinel_t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!i.in_stream}. \end{itemdescr} \indexlibrarymember{operator"!=}{istream_iterator}% @@ -2722,6 +5893,8 @@ template bool operator!=(const istream_iterator& x, const istream_iterator& y); +friend bool operator!=(default_sentinel_t x, const istream_iterator& y); +friend bool operator!=(const istream_iterator& x, default_sentinel_t y); \end{itemdecl} \begin{itemdescr} @@ -2764,13 +5937,14 @@ public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = void; + using difference_type = ptrdiff_t; using pointer = void; using reference = void; using char_type = charT; using traits_type = traits; using ostream_type = basic_ostream; + constexpr ostreambuf_iterator() noexcept = default; ostream_iterator(ostream_type& s); ostream_iterator(ostream_type& s, const charT* delimiter); ostream_iterator(const ostream_iterator& x); @@ -2783,14 +5957,13 @@ ostream_iterator& operator++(int); private: - basic_ostream* out_stream; // \expos - const charT* delim; // \expos + basic_ostream* out_stream = nullptr; // \expos + const charT* delim = nullptr; // \expos }; } \end{codeblock} -\rSec3[ostream.iterator.cons.des]{\tcode{ostream_iterator} constructors and destructor} - +\rSec3[ostream.iterator.cons.des]{Constructors and destructor} \indexlibrary{\idxcode{ostream_iterator}!constructor}% \begin{itemdecl} @@ -2840,7 +6013,7 @@ The iterator is destroyed. \end{itemdescr} -\rSec3[ostream.iterator.ops]{\tcode{ostream_iterator} operations} +\rSec3[ostream.iterator.ops]{Operations} \indexlibrarymember{operator=}{ostream_iterator}% \begin{itemdecl} @@ -2941,6 +6114,7 @@ class proxy; // \expos constexpr istreambuf_iterator() noexcept; + constexpr istreambuf_iterator(default_sentinel_t) noexcept; istreambuf_iterator(const istreambuf_iterator&) noexcept = default; ~istreambuf_iterator() = default; istreambuf_iterator(istream_type& s) noexcept; @@ -2952,6 +6126,11 @@ proxy operator++(int); bool equal(const istreambuf_iterator& b) const; + friend bool operator==(default_sentinel_t s, const istreambuf_iterator& i); + friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); + friend bool operator!=(default_sentinel_t a, const istreambuf_iterator& b); + friend bool operator!=(const istreambuf_iterator& a, default_sentinel_t b); + private: streambuf_type* sbuf_; // \expos }; @@ -2996,7 +6175,7 @@ It keeps the character pointed to by the previous value of the iterator for some possible future access to get the character. -\rSec3[istreambuf.iterator.cons]{\tcode{istreambuf_iterator} constructors} +\rSec3[istreambuf.iterator.cons]{Constructors} \pnum For each \tcode{istreambuf_iterator} constructor in this subclause, @@ -3007,6 +6186,7 @@ \indexlibrary{\idxcode{istreambuf_iterator}!constructor}% \begin{itemdecl} constexpr istreambuf_iterator() noexcept; +constexpr istreambuf_iterator(default_sentinel_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3051,7 +6231,7 @@ Initializes \tcode{sbuf_} with \tcode{p.sbuf_}. \end{itemdescr} -\rSec3[istreambuf.iterator.ops]{\tcode{istreambuf_iterator} operations} +\rSec3[istreambuf.iterator.ops]{Operations} \indexlibrarymember{operator*}{istreambuf_iterator}% \begin{itemdecl} @@ -3121,11 +6301,24 @@ \tcode{a.equal(b)}. \end{itemdescr} +\indexlibrarymember{operator==}{istreambuf_iterator}% +\begin{itemdecl} +friend bool operator==(default_sentinel_t s, const istreambuf_iterator& i); +friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{i.equal(s)}. +\end{itemdescr} + \indexlibrarymember{operator"!=}{istreambuf_iterator}% \begin{itemdecl} template bool operator!=(const istreambuf_iterator& a, const istreambuf_iterator& b); +friend bool operator!=(default_sentinel_t a, const istreambuf_iterator& b); +friend bool operator!=(const istreambuf_iterator& a, default_sentinel_t b); \end{itemdecl} \begin{itemdescr} @@ -3144,7 +6337,7 @@ public: using iterator_category = output_iterator_tag; using value_type = void; - using difference_type = void; + using difference_type = ptrdiff_t; using pointer = void; using reference = void; using char_type = charT; @@ -3152,6 +6345,7 @@ using streambuf_type = basic_streambuf; using ostream_type = basic_ostream; + constexpr ostreambuf_iterator() noexcept = default; ostreambuf_iterator(ostream_type& s) noexcept; ostreambuf_iterator(streambuf_type* s) noexcept; ostreambuf_iterator& operator=(charT c); @@ -3162,7 +6356,7 @@ bool failed() const noexcept; private: - streambuf_type* sbuf_; // \expos + streambuf_type* sbuf_ = nullptr; // \expos }; } \end{codeblock} @@ -3176,8 +6370,7 @@ onto the output stream from which it was constructed. It is not possible to get a character value out of the output iterator. -\rSec3[ostreambuf.iter.cons]{\tcode{ostreambuf_iterator} constructors} - +\rSec3[ostreambuf.iter.cons]{Constructors} \indexlibrary{\idxcode{ostreambuf_iterator}!constructor}% \begin{itemdecl} @@ -3212,7 +6405,7 @@ Initializes \tcode{sbuf_} with \tcode{s}. \end{itemdescr} -\rSec3[ostreambuf.iter.ops]{\tcode{ostreambuf_iterator} operations} +\rSec3[ostreambuf.iter.ops]{Operations} \indexlibrarymember{operator=}{ostreambuf_iterator}% \begin{itemdecl} diff --git a/source/lex.tex b/source/lex.tex index a6e35a6633..4650f265c4 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -670,101 +670,90 @@ as keywords (that is, they are unconditionally treated as keywords in phase 7) except in an \grammarterm{attribute-token}\iref{dcl.attr.grammar}: -\begin{floattable}{Keywords}{tab:keywords} +\begin{multicolfloattable}{Keywords}{tab:keywords} {lllll} -\topline - -\tcode{alignas} & -\tcode{const_cast} & -\tcode{for} & -\tcode{public} & -\tcode{thread_local} \\ - -\tcode{alignof} & -\tcode{continue} & -\tcode{friend} & -\tcode{register} & -\tcode{throw} \\ - -\tcode{asm} & -\tcode{decltype} & -\tcode{goto} & -\tcode{reinterpret_cast} & -\tcode{true} \\ - -\tcode{auto} & -\tcode{default} & -\tcode{if} & -\tcode{requires} & -\tcode{try} \\ - -\tcode{bool} & -\tcode{delete} & -\tcode{inline} & -\tcode{return} & -\tcode{typedef} \\ - -\tcode{break} & -\tcode{do} & -\tcode{int} & -\tcode{short} & -\tcode{typeid} \\ - -\tcode{case} & -\tcode{double} & -\tcode{long} & -\tcode{signed} & -\tcode{typename} \\ - -\tcode{catch} & -\tcode{dynamic_cast} & -\tcode{mutable} & -\tcode{sizeof} & -\tcode{union} \\ - -\tcode{char} & -\tcode{else} & -\tcode{namespace} & -\tcode{static} & -\tcode{unsigned} \\ - -\tcode{char16_t} & -\tcode{enum} & -\tcode{new} & -\tcode{static_assert} & -\tcode{using} \\ - -\tcode{char32_t} & -\tcode{explicit} & -\tcode{noexcept} & -\tcode{static_cast} & -\tcode{virtual} \\ - -\tcode{class} & -\tcode{export} & -\tcode{nullptr} & -\tcode{struct} & -\tcode{void} \\ - -\tcode{concept} & -\tcode{extern} & -\tcode{operator} & -\tcode{switch} & -\tcode{volatile} \\ - -\tcode{const} & -\tcode{false} & -\tcode{private} & -\tcode{template} & -\tcode{wchar_t} \\ - -\tcode{constexpr} & -\tcode{float} & -\tcode{protected} & -\tcode{this} & -\tcode{while} \\ - -\end{floattable} +\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} \\ +\columnbreak +\tcode{constexpr} \\ +\tcode{const_cast} \\ +\tcode{continue} \\ +\tcode{decltype} \\ +\tcode{default} \\ +\tcode{delete} \\ +\tcode{double} \\ +\tcode{do} \\ +\tcode{dynamic_cast} \\ +\tcode{else} \\ +\tcode{enum} \\ +\tcode{explicit} \\ +\tcode{export} \\ +\tcode{extern} \\ +\tcode{false} \\ +\tcode{float} \\ +\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} \\ +\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} \\ +\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} \\ +\end{multicolfloattable} \begin{note} The \tcode{export} and \tcode{register} keywords are unused but are reserved for future use.\end{note} @@ -1138,7 +1127,7 @@ A character literal that begins with \tcode{u8}, such as \tcode{u8'w'}, \indextext{prefix!\idxcode{u8}}% -is a character literal of type \tcode{char}, +is a character literal of type \tcode{char8_t}, known as a \defn{UTF-8 character literal}. The value of a UTF-8 character literal is equal to its ISO/IEC 10646 code point value, @@ -1528,28 +1517,30 @@ \pnum \indextext{string!type of}% \indextext{literal!string!narrow}% -After translation phase 6, a \grammarterm{string-literal} that does not begin with an \grammarterm{encoding-prefix} is an -\defn{ordinary string literal}, and is initialized with the given characters. +After translation phase 6, a \grammarterm{string-literal} +that does not begin with an \grammarterm{encoding-prefix} is an +\defn{ordinary string literal}. +An ordinary string literal +has type ``array of \placeholder{n} \tcode{const char}'' +where \placeholder{n} is the size of the string as defined below, +has static storage duration\iref{basic.stc}, and +is initialized with the given characters. \pnum \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}. +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 +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 +the value of the corresponding code unit of the UTF-8 encoding of the string. \pnum Ordinary string literals and UTF-8 string literals are -also referred to as narrow -string literals. A narrow string literal has type -\indextext{literal!string!type of}% -``array of \placeholder{n} \tcode{const char}'', where \placeholder{n} is the size of -the string as defined below, and has static storage -duration\iref{basic.stc}. - -\pnum -For a UTF-8 string literal, each successive element of the object -representation\iref{basic.types} has the value of the corresponding -code unit of the UTF-8 encoding of the string. +also referred to as narrow string literals. \pnum \indextext{literal!string!\idxcode{char16_t}}% @@ -1655,7 +1646,7 @@ \tcode{char16_t} 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} element due to \defnadj{multibyte}{encoding}. The +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 diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 97c96f01f2..678d6dbc94 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -30,6 +30,7 @@ \ref{strings} & & Strings library \\ \ref{containers} & & Containers library \\ \ref{iterators} & & Iterators library \\ +\ref{ranges} & & Ranges library \\ \ref{algorithms} & & Algorithms library \\ \ref{numerics} & & Numerics library \\ \ref{time} & & Time library \\ @@ -64,14 +65,11 @@ \pnum The strings library\iref{strings} provides support for manipulating text represented -as sequences of type -\tcode{char}, -sequences of type -\tcode{char16_t}, -sequences of type -\tcode{char32_t}, -sequences of type -\tcode{wchar_t}, +as sequences of type \tcode{char}, +sequences of type \tcode{char8_t}, +sequences of type \tcode{char16_t}, +sequences of type \tcode{char32_t}, +sequences of type \tcode{wchar_t}, and sequences of any other character-like type. \pnum @@ -79,7 +77,7 @@ support for text processing. \pnum -The containers\iref{containers}, iterators\iref{iterators}, +The containers\iref{containers}, iterators\iref{iterators}, ranges\iref{ranges}, and algorithms\iref{algorithms} libraries provide a \Cpp{} program with access to a subset of the most widely used algorithms and data structures. @@ -157,6 +155,7 @@ \begin{defnote} The term does not mean only \tcode{char}, +\tcode{char8_t}, \tcode{char16_t}, \tcode{char32_t}, and @@ -330,6 +329,22 @@ extensions\iref{intro.compliance} and internal types used by the library. \end{defnote} +\definition{projection}{defns.projection} +\indexdefn{projection}% +\defncontext{function object argument} transformation that +an algorithm applies before inspecting the values of elements + +\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; }); +\end{codeblock} +sorts the pairs in increasing order of their \tcode{first} members: +\begin{codeblock} +{{0, "baz"}, {1, "bar"}, {2, "foo"}} +\end{codeblock} +\end{example} + \definition{referenceable type}{defns.referenceable} \indexdefn{type!referenceable}% type that is either an @@ -444,10 +459,10 @@ \begin{itemize} \item macros \item values -\item types +\item types and alias templates \item classes and class templates \item functions and function templates -\item objects +\item objects and variable templates \item concepts \end{itemize} @@ -1224,6 +1239,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1235,8 +1251,8 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1464,6 +1480,7 @@ \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ \rowsep +\ref{concepts} & Concepts library & \tcode{} \\ \rowsep \ref{meta} & Type traits & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ \rowsep \ref{atomics} & Atomics & \tcode{} \\ \rowsep @@ -1850,18 +1867,18 @@ Expression & Return type & Operational semantics \\ \capsep \tcode{P u(np);}\br & & - \postconditions \tcode{u == nullptr} \\ + \ensures \tcode{u == nullptr} \\ \tcode{P u = np;} & & \\ \rowsep \tcode{P(np)} & & - \postconditions \tcode{P(np) == nullptr} \\ \rowsep + \ensures \tcode{P(np) == nullptr} \\ \rowsep \tcode{t = np} & \tcode{P\&} & - \postconditions \tcode{t == nullptr} \\ \rowsep + \ensures \tcode{t == nullptr} \\ \rowsep \tcode{a != b} & contextually convertible to \tcode{bool} & @@ -1929,7 +1946,7 @@ difference, the type of the size of objects in this allocation model, as well as the memory allocation and deallocation primitives for it. All of the string types\iref{strings}, -containers\iref{containers} (except array), +containers\iref{containers} (except \tcode{array}), string buffers and string streams\iref{input.output}, and \tcode{match_results}\iref{re} are parameterized in terms of allocators. @@ -2119,23 +2136,23 @@ \tcode{X u = a;} & & Shall not exit via an exception.\br - \postconditions \tcode{u == a} & \\ \rowsep + \ensures \tcode{u == a} & \\ \rowsep \tcode{X u(b);} & & Shall not exit via an exception.\br - \postconditions \tcode{Y(u) == b}, \tcode{u == X(b)} & \\ \rowsep + \ensures \tcode{Y(u) == b}, \tcode{u == X(b)} & \\ \rowsep \tcode{X u(std::move(a));} \br \tcode{X u = std::move(a);} & & Shall not exit via an exception.\br - \postconditions The value of \tcode{a} is unchanged and is equal to \tcode{u}. & \\ \rowsep + \ensures The value of \tcode{a} is unchanged and is equal to \tcode{u}. & \\ \rowsep \tcode{X u(std::move(b));} & & Shall not exit via an exception.\br - \postconditions \tcode{u} is equal to the prior value of \tcode{X(b)}. & \\ \rowsep + \ensures \tcode{u} is equal to the prior value of \tcode{X(b)}. & \\ \rowsep \tcode{a.construct(c, args)}& (not used) & @@ -2214,17 +2231,22 @@ and the \tcode{swap} operation shall not throw exceptions. \pnum -An allocator type \tcode{X} shall satisfy the +An allocator type \tcode{X} shall meet the \oldconcept{CopyConstructible} requirements (\tref{copyconstructible}). The \tcode{X::pointer}, \tcode{X::const_pointer}, \tcode{X::void_pointer}, and -\tcode{X::const_void_pointer} types shall satisfy the +\tcode{X::const_void_pointer} types shall meet the \oldconcept{Nullable\-Pointer} requirements (\tref{nullablepointer}). No constructor, comparison function, copy operation, move operation, or swap operation on these pointer types shall exit via an exception. \tcode{X::pointer} and \tcode{X::const_pointer} shall also -satisfy the requirements for -a random access iterator\iref{random.access.iterators} and of -a contiguous iterator\iref{iterator.requirements.general}. +meet the requirements for +a \oldconcept{RandomAccessIterator}\iref{random.access.iterators} and +the additional requirement that, when \tcode{a} and \tcode{(a + n)} are +dereferenceable pointer values for some integral value \tcode{n}, +\begin{codeblock} +addressof(*(a + n)) == addressof(*a) + n +\end{codeblock} +is \tcode{true}. \pnum Let \tcode{x1} and \tcode{x2} denote objects of (possibly different) types @@ -2579,9 +2601,13 @@ \pnum \indextext{unit!translation}% A translation unit shall not \tcode{\#define} or \tcode{\#undef} -names lexically identical to keywords, to the identifiers listed in -\tref{identifiers.special}, or to the \grammarterm{attribute-token}{s} described -in~\ref{dcl.attr}. +names lexically identical +to keywords, +to the identifiers listed in \tref{identifiers.special}, +to the \grammarterm{attribute-token}{s} described in~\ref{dcl.attr}, or +to the identifiers \tcode{expects} or \tcode{ensures}, +except that the names \tcode{likely} and \tcode{unlikely} may be +defined as function-like macros~\iref{cpp.replace}. \rSec4[extern.names]{External linkage} diff --git a/source/locales.tex b/source/locales.tex index f47093a319..da9cff27cd 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -349,8 +349,8 @@ collate & \tcode{collate}, \tcode{collate} \\ \rowsep ctype & \tcode{ctype}, \tcode{ctype} \\ & \tcode{codecvt} \\ - & \tcode{codecvt} \\ - & \tcode{codecvt} \\ + & \tcode{codecvt} \\ + & \tcode{codecvt} \\ & \tcode{codecvt} \\ \rowsep monetary & \tcode{moneypunct}, \tcode{moneypunct} \\ & \tcode{moneypunct}, \tcode{moneypunct} \\ @@ -390,8 +390,8 @@ collate & \tcode{collate_byname}, \tcode{collate_byname} \\ \rowsep ctype & \tcode{ctype_byname}, \tcode{ctype_byname} \\ & \tcode{codecvt_byname} \\ - & \tcode{codecvt_byname} \\ - & \tcode{codecvt_byname} \\ + & \tcode{codecvt_byname} \\ + & \tcode{codecvt_byname} \\ & \tcode{codecvt_byname} \\ \rowsep monetary & \tcode{moneypunct_byname} \\ & \tcode{moneypunct_byname} \\ @@ -1526,7 +1526,7 @@ } \end{codeblock} -\rSec3[facet.ctype.special]{\tcode{ctype} specializations} +\rSec3[facet.ctype.special]{\tcode{ctype} specialization} \indexlibrary{\idxcode{ctype}}% \begin{codeblock} @@ -1595,7 +1595,7 @@ \tcode{table_size} is at least 256. -\rSec4[facet.ctype.char.dtor]{\tcode{ctype} destructor} +\rSec4[facet.ctype.char.dtor]{Destructor} \indexlibrary{\idxcode{ctype}!destructor}% \begin{itemdecl} @@ -1610,7 +1610,7 @@ \tcode{delete [] table()}. \end{itemdescr} -\rSec4[facet.ctype.char.members]{\tcode{ctype} members} +\rSec4[facet.ctype.char.members]{Members} \pnum \indexlibrary{\idxcode{ctype}!\idxcode{ctype}}% @@ -1779,7 +1779,7 @@ \tcode{classic_table()}. \end{itemdescr} -\rSec4[facet.ctype.char.statics]{\tcode{ctype} static members} +\rSec4[facet.ctype.char.statics]{Static members} \indexlibrarymember{ctype}{classic_table}% \begin{itemdecl} @@ -1794,7 +1794,7 @@ which represents the classifications of characters in the \tcode{"C"} locale. \end{itemdescr} -\rSec4[facet.ctype.char.virtuals]{\tcode{ctype} virtual functions} +\rSec4[facet.ctype.char.virtuals]{Virtual functions} \indexlibrarymember{ctype}{do_toupper}% \indexlibrarymember{ctype}{do_tolower}% @@ -1900,12 +1900,12 @@ \tcode{codecvt} implements a degenerate conversion; it does not convert at all. -The specialization \tcode{codecvt} +The specialization \tcode{codecvt} converts between the UTF-16 and UTF-8 encoding forms, and -the specialization \tcode{codecvt} \tcode{} +the specialization \tcode{codecvt} \tcode{} converts between the UTF-32 and UTF-8 encoding forms. \tcode{codecvt} -converts between the native character sets for narrow and wide characters. +converts between the native character sets for ordinary and wide characters. Specializations on \tcode{mbstate_t} perform conversion between encodings known to the library implementer. @@ -1921,7 +1921,7 @@ \tcode{do_out} members. -\rSec4[locale.codecvt.members]{\tcode{codecvt} members} +\rSec4[locale.codecvt.members]{Members} \indexlibrarymember{codecvt}{out}% \begin{itemdecl} @@ -2006,7 +2006,7 @@ \tcode{do_max_length()}. \end{itemdescr} -\rSec4[locale.codecvt.virtuals]{\tcode{codecvt} virtual functions} +\rSec4[locale.codecvt.virtuals]{Virtual functions} \indexlibrarymember{codecvt}{do_out}% \indexlibrarymember{codecvt}{do_in}% @@ -2415,7 +2415,7 @@ \tcode{num_get} is used to parse numeric values from an input sequence such as an istream. -\rSec4[facet.num.get.members]{\tcode{num_get} members} +\rSec4[facet.num.get.members]{Members} \indexlibrarymember{num_get}{get}% \begin{itemdecl} @@ -2449,7 +2449,7 @@ \tcode{do_get(in, end, str, err, val)}. \end{itemdescr} -\rSec4[facet.num.get.virtuals]{\tcode{num_get} virtual functions} +\rSec4[facet.num.get.virtuals]{Virtual functions} \indexlibrarymember{num_get}{do_get}% \begin{itemdecl} @@ -2801,7 +2801,7 @@ \tcode{num_put} is used to format numeric values to a character sequence such as an ostream. -\rSec4[facet.num.put.members]{\tcode{num_put} members} +\rSec4[facet.num.put.members]{Members} \indexlibrarymember{num_put}{put}% \begin{itemdecl} @@ -2821,7 +2821,7 @@ \tcode{do_put(out, str, fill, val)}. \end{itemdescr} -\rSec4[facet.num.put.virtuals]{\tcode{num_put} virtual functions} +\rSec4[facet.num.put.virtuals]{Virtual functions} \indexlibrarymember{num_put}{do_put}% \begin{itemdecl} @@ -3178,7 +3178,7 @@ portion contains no thousands-separators, no grouping constraint is applied. -\rSec4[facet.numpunct.members]{\tcode{numpunct} members} +\rSec4[facet.numpunct.members]{Members} \indexlibrarymember{numpunct}{decimal_point}% \begin{itemdecl} @@ -3229,7 +3229,7 @@ respectively. \end{itemdescr} -\rSec4[facet.numpunct.virtuals]{\tcode{numpunct} virtual functions} +\rSec4[facet.numpunct.virtuals]{Virtual functions} \indexlibrarymember{numpunct}{do_decimal_point}% \begin{itemdecl} @@ -3380,7 +3380,7 @@ in the range \range{low}{high}. -\rSec4[locale.collate.members]{\tcode{collate} members} +\rSec4[locale.collate.members]{Members} \indexlibrarymember{collate}{compare}% \begin{itemdecl} @@ -3416,7 +3416,7 @@ \tcode{do_hash(low, high)}. \end{itemdescr} -\rSec4[locale.collate.virtuals]{\tcode{collate} virtual functions} +\rSec4[locale.collate.virtuals]{Virtual functions} \indexlibrarymember{collate}{do_compare}% \begin{itemdecl} @@ -3605,7 +3605,7 @@ \tcode{ios_base::eof\-bit} in \tcode{err}. -\rSec4[locale.time.get.members]{\tcode{time_get} members} +\rSec4[locale.time.get.members]{Members} \indexlibrarymember{time_get}{date_order}% \begin{itemdecl} @@ -3747,7 +3747,7 @@ \returns \tcode{s}. \end{itemdescr} -\rSec4[locale.time.get.virtuals]{\tcode{time_get} virtual functions} +\rSec4[locale.time.get.virtuals]{Virtual functions} \indexlibrarymember{time_get}{do_date_order}% \begin{itemdecl} @@ -3981,7 +3981,7 @@ } \end{codeblock} -\rSec4[locale.time.put.members]{\tcode{time_put} members} +\rSec4[locale.time.put.members]{Members} \indexlibrarymember{time_put}{put}% \begin{itemdecl} @@ -4048,7 +4048,7 @@ An iterator pointing immediately after the last character produced. \end{itemdescr} -\rSec4[locale.time.put.virtuals]{\tcode{time_put} virtual functions} +\rSec4[locale.time.put.virtuals]{Virtual functions} \indexlibrarymember{time_put}{do_put}% \begin{itemdecl} @@ -4164,7 +4164,7 @@ } \end{codeblock} -\rSec4[locale.money.get.members]{\tcode{money_get} members} +\rSec4[locale.money.get.members]{Members} \indexlibrarymember{money_get}{get}% \begin{itemdecl} @@ -4180,7 +4180,7 @@ \tcode{do_get(s, end, intl, f, err, quant)}. \end{itemdescr} -\rSec4[locale.money.get.virtuals]{\tcode{money_get} virtual functions} +\rSec4[locale.money.get.virtuals]{Virtual functions} \indexlibrarymember{money_get}{do_get}% \begin{itemdecl} @@ -4388,7 +4388,7 @@ } \end{codeblock} -\rSec4[locale.money.put.members]{\tcode{money_put} members} +\rSec4[locale.money.put.members]{Members} \indexlibrarymember{money_put}{put}% \begin{itemdecl} @@ -4402,7 +4402,7 @@ \tcode{do_put(s, intl, f, loc, quant)}. \end{itemdescr} -\rSec4[locale.money.put.virtuals]{\tcode{money_put} virtual functions} +\rSec4[locale.money.put.virtuals]{Virtual functions} \indexlibrarymember{money_put}{do_put}% \begin{itemdecl} @@ -4696,7 +4696,7 @@ defined identically as the member \tcode{numpunct<>::do_grouping()}. -\rSec4[locale.moneypunct.members]{\tcode{moneypunct} members} +\rSec4[locale.moneypunct.members]{Members} \indexlibrarymember{moneypunct}{decimal_point}% \indexlibrarymember{moneypunct}{thousands_sep}% @@ -4725,7 +4725,7 @@ virtual member function \tcode{do_\placeholder{F}()}. -\rSec4[locale.moneypunct.virtuals]{\tcode{moneypunct} virtual functions} +\rSec4[locale.moneypunct.virtuals]{Virtual functions} \indexlibrarymember{moneypunct}{do_decimal_point}% \begin{itemdecl} @@ -4913,7 +4913,7 @@ can be obtained only by calling member \tcode{open}. -\rSec4[locale.messages.members]{\tcode{messages} members} +\rSec4[locale.messages.members]{Members} \indexlibrarymember{messages}{open}% \begin{itemdecl} @@ -4949,7 +4949,7 @@ \tcode{do_close(cat)}. \end{itemdescr} -\rSec4[locale.messages.virtuals]{\tcode{messages} virtual functions} +\rSec4[locale.messages.virtuals]{Virtual functions} \indexlibrarymember{messages}{do_open}% \begin{itemdecl} diff --git a/source/macros.tex b/source/macros.tex index b371dc8ef9..80806966b4 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -245,7 +245,6 @@ \newcommand{\expects}{\Fundesc{Expects}} \newcommand{\effects}{\Fundesc{Effects}} \newcommand{\ensures}{\Fundesc{Ensures}} -\newcommand{\postconditions}{\ensures} \newcommand{\returns}{\Fundesc{Returns}} \newcommand{\throws}{\Fundesc{Throws}} \newcommand{\default}{\Fundesc{Default behavior}} @@ -297,6 +296,8 @@ \newcommand{\unspecbool}{\UNSP{unspecified-bool-type}} \newcommand{\seebelow}{\UNSP{see below}} \newcommand{\seebelownc}{\UNSPnc{see below}} +\newcommand{\seeref}[1]{\UNSP{see~\ref{#1}}} +\newcommand{\seerefnc}[1]{\UNSPnc{see~\ref{#1}}} \newcommand{\unspecuniqtype}{\UNSP{unspecified unique type}} \newcommand{\unspecalloctype}{\UNSP{unspecified allocator type}} @@ -336,14 +337,16 @@ \newcommand{\range}[2]{\Range{[}{)}{#1}{#2}} %% Change descriptions -\newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\space} +\newcommand{\diffhead}[1]{\textbf{#1:}\space} +\newcommand{\diffdef}[1]{\hfill\break\diffhead{#1}} \newcommand{\diffref}[1]{\pnum\textbf{Affected subclause:} \ref{#1}} \newcommand{\diffrefs}[2]{\pnum\textbf{Affected subclauses:} \ref{#1}, \ref{#2}} % \nodiffref swallows a following \change and removes the preceding line break. -\def\nodiffref\change{\pnum\textbf{Change:}\space} +\def\nodiffref\change{\pnum\diffhead{Change}} \newcommand{\change}{\diffdef{Change}} \newcommand{\rationale}{\diffdef{Rationale}} \newcommand{\effect}{\diffdef{Effect on original feature}} +\newcommand{\effectafteritemize}{\diffhead{Effect on original feature}} \newcommand{\difficulty}{\diffdef{Difficulty of converting}} \newcommand{\howwide}{\diffdef{How widely used}} @@ -492,25 +495,6 @@ \let\ncbnf\bnf \let\endncbnf\endbnf -%%-------------------------------------------------- -%% Drawing environment -% -% usage: \begin{drawing}{UNITLENGTH}{WIDTH}{HEIGHT}{CAPTION} -\newenvironment{drawing}[4] -{ -\newcommand{\mycaption}{#4} -\begin{figure}[h] -\setlength{\unitlength}{#1} -\begin{center} -\begin{picture}(#2,#3)\thicklines -} -{ -\end{picture} -\end{center} -\caption{\mycaption} -\end{figure} -} - %%-------------------------------------------------- %% Environment for imported graphics % usage: \begin{importgraphic}{CAPTION}{TAG}{FILE} @@ -526,17 +510,6 @@ \caption{\cptn}\label{\lbl}% \end{figure}} -%% enumeration display overrides -% enumerate with lowercase letters -\newenvironment{enumeratea} -{ - \renewcommand{\labelenumi}{\alph{enumi})} - \begin{enumerate} -} -{ - \end{enumerate} -} - %%-------------------------------------------------- %% Definitions section for "Terms and definitions" \newcounter{termnote} diff --git a/source/numerics.tex b/source/numerics.tex index dc15325e36..7f85dc7b2e 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17,7 +17,6 @@ as summarized in \tref{numerics.lib.summary}. \begin{libsumtab}{Numerics library summary}{tab:numerics.lib.summary} -\ref{numerics.defns} & Definitions & \\ \ref{numeric.requirements} & Requirements & \\ \rowsep \ref{cfenv} & Floating-point environment & \tcode{} \\ \rowsep \ref{complex.numbers} & Complex numbers & \tcode{} \\ \rowsep @@ -28,28 +27,6 @@ & floating-point types & \tcode{} \\ \end{libsumtab} -\rSec1[numerics.defns]{Definitions} - -\indexlibrary{generalized_noncommutative_sum@\tcode{\placeholder{GENERALIZED_NONCOMMUTATIVE_SUM}}}% -\pnum -Define \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aN)} as follows: -\begin{itemize} -\item -\tcode{a1} when \tcode{N} is \tcode{1}, otherwise - -\item -\tcode{op(\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aK),} \\ -\tcode{\phantom{op(}\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, ..., aN))} -for any \tcode{K} where $1 < \mathtt{K}+1 = \mathtt{M} \leq \mathtt{N}$. -\end{itemize} - -\indexlibrary{generalized_sum@\tcode{\placeholder{GENERALIZED_SUM}}}% -\pnum -Define \tcode{\placeholdernc{GENERALIZED_SUM}(op, a1, ..., aN)} as -\tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, ..., bN)}, -where -\tcode{b1, ..., bN} may be any permutation of \tcode{a1, ..., aN}. - \rSec1[numeric.requirements]{Numeric type requirements} \indextext{requirements!numeric type} @@ -292,7 +269,7 @@ // \ref{complex}, class template \tcode{complex} template class complex; - // \ref{complex.special}, \tcode{complex} specializations + // \ref{complex.special}, specializations template<> class complex; template<> class complex; template<> class complex; @@ -428,7 +405,7 @@ of a complex number. -\rSec2[complex.special]{\tcode{complex} specializations} +\rSec2[complex.special]{Specializations} \begin{codeblock} namespace std { @@ -518,7 +495,7 @@ } \end{codeblock} -\rSec2[complex.members]{\tcode{complex} member functions} +\rSec2[complex.members]{Member functions} \indexlibrary{\idxcode{complex}!constructor}% \begin{itemdecl} @@ -532,7 +509,7 @@ \tcode{complex}. \pnum -\postconditions +\ensures \tcode{real() == re \&\& imag() == im}. \end{itemdescr} @@ -576,7 +553,7 @@ \effects Assigns \tcode{val} to the imaginary component. \end{itemdescr} -\rSec2[complex.member.ops]{\tcode{complex} member operators} +\rSec2[complex.member.ops]{Member operators} \indexlibrarymember{operator+=}{complex}% \begin{itemdecl} @@ -724,7 +701,7 @@ \tcode{*this}. \end{itemdescr} -\rSec2[complex.ops]{\tcode{complex} non-member operations} +\rSec2[complex.ops]{Non-member operations} \indexlibrarymember{operator+}{complex}% \begin{itemdecl} @@ -915,7 +892,7 @@ \end{note} \end{itemdescr} -\rSec2[complex.value.ops]{\tcode{complex} value operations} +\rSec2[complex.value.ops]{Value operations} \indexlibrary{\idxcode{real}!\idxcode{complex}}% \begin{itemdecl} @@ -1006,7 +983,7 @@ \begin{itemdescr} \pnum \requires -\tcode{rho} shall be non-negative and non-NaN. \tcode{theta} shall be finite. +\tcode{rho} shall be non-negative and non-NaN\@. \tcode{theta} shall be finite. \pnum \returns @@ -1017,7 +994,7 @@ is \tcode{theta}. \end{itemdescr} -\rSec2[complex.transcendentals]{\tcode{complex} transcendentals} +\rSec2[complex.transcendentals]{Transcendentals} \indexlibrary{\idxcode{acos}!\idxcode{complex}}% \indexlibrary{\idxcode{cacos}!\idxcode{complex}}% @@ -1565,7 +1542,7 @@ With \tcode{T} as the \tcode{result_type} thus associated with such an entity, that entity is characterized: -\begin{enumeratea} +\begin{itemize} \item as \term{boolean} or equivalently as \term{boolean-valued}, if \tcode{T} is \tcode{bool}; @@ -1576,7 +1553,7 @@ \item otherwise as \term{floating} or equivalently as \term{real-valued}. -\end{enumeratea} +\end{itemize} \noindent If integer-valued, an entity may optionally be further characterized as @@ -1596,7 +1573,7 @@ denote the respective conventional bitwise operations. Further: -\begin{enumeratea} +\begin{itemize} \item the operator \rightshift{} denotes a bitwise right shift with zero-valued bits appearing in the high bits of the result, and @@ -1604,7 +1581,7 @@ the operator \leftshift{w} denotes a bitwise left shift with zero-valued bits appearing in the low bits of the result, and whose result is always taken modulo $2^w$. -\end{enumeratea} +\end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1783,7 +1760,7 @@ \pnum Throughout this subclause \ref{rand}, the effect of instantiating a template: -\begin{enumeratea} +\begin{itemize} \item that has a template type parameter named \tcode{Sseq} @@ -1838,7 +1815,7 @@ \tcode{unsigned long}, or \tcode{unsigned long long}. -\end{enumeratea} +\end{itemize} \pnum Throughout this subclause \ref{rand}, @@ -1886,7 +1863,7 @@ and if \tcode{S} also satisfies all other requirements of this subclause \ref{rand.req.seedseq}. In that Table and throughout this subclause: -\begin{enumeratea} +\begin{itemize} \item \tcode{T} is the type named by \tcode{S}'s associated \tcode{result_type}; @@ -1905,7 +1882,7 @@ and \item \tcode{il} is a value of \tcode{initializer_list}. -\end{enumeratea} +\end{itemize} \begin{libreqtab4d} @@ -2022,8 +1999,8 @@ concept UniformRandomBitGenerator = Invocable && UnsignedIntegral> && requires { - G::min(); requires Same>; - G::max(); requires Same>; + { G::min() } -> Same>; + { G::max() } -> Same>; }; \end{codeblock} @@ -2082,7 +2059,7 @@ \pnum \tcode{E}'s specification shall define: -\begin{enumeratea} +\begin{itemize} \item the size of \tcode{E}'s state in multiples of the size of \tcode{result_type}, @@ -2099,7 +2076,7 @@ $\mathsf{GA}$ by which an engine's state is mapped to a value of type \tcode{result_type}. -\end{enumeratea} +\end{itemize} \pnum A class \tcode{E} @@ -2113,7 +2090,7 @@ and if \tcode{E} also satisfies all other requirements of this subclause \ref{rand.req.eng}. In that Table and throughout this subclause: -\begin{enumeratea} +\begin{itemize} \item \tcode{T} is the type named by \tcode{E}'s associated \tcode{result_type}; @@ -2136,7 +2113,7 @@ \item \tcode{is} is an lvalue of the type of some class template specialization \tcode{basic_istream}; -\end{enumeratea} +\end{itemize} where \tcode{charT} and \tcode{traits} are constrained according to \ref{strings} and \ref{input.output}. @@ -2200,21 +2177,21 @@ \tcode{e.seed()}% \indextext{\idxcode{seed}!random number engine requirement} & \tcode{void} - & \postconditions + & \ensures \tcode{e == E()}. & same as \tcode{E()} \\ \rowsep \tcode{e.seed(s)}% \indextext{\idxcode{seed}!random number engine requirement} & \tcode{void} - & \postconditions + & \ensures \tcode{e == E(s)}. & same as \tcode{E(s)} \\ \rowsep \tcode{e.seed(q)}% \indextext{\idxcode{seed}!random number engine requirement} & \tcode{void} - & \postconditions + & \ensures \tcode{e == E(q)}. & same as \tcode{E(q)} \\ \rowsep @@ -2278,7 +2255,7 @@ adjacent numbers are separated by one or more space characters. - \postconditions The \tcode{os.}\textit{fmtflags} and fill character are unchanged. + \ensures The \tcode{os.}\textit{fmtflags} and fill character are unchanged. & \bigoh{$\text{size of state}$} \\ \rowsep \tcode{is >> v}% @@ -2309,7 +2286,7 @@ \tcode{charT} and \tcode{traits} were respectively the same as those of \tcode{is}. - \postconditions The \tcode{is.}\textit{fmtflags} are unchanged. + \ensures The \tcode{is.}\textit{fmtflags} are unchanged. & \bigoh{$\text{size of state}$} \\ \end{libreqtab4d} @@ -2424,7 +2401,7 @@ \pnum \tcode{A} shall also satisfy the following additional requirements: -\begin{enumeratea} +\begin{itemize} \item The complexity of each function @@ -2448,7 +2425,7 @@ of \tcode{A} shall include the textual representation of its base engine. -\end{enumeratea} +\end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Random Number Distribution requirements: @@ -2497,7 +2474,7 @@ also satisfy all other requirements of this subclause \ref{rand.req.dist}. In that Table and throughout this subclause, -\begin{enumeratea} +\begin{itemize} \item \tcode{T} is the type named by \tcode{D}'s associated \tcode{result_type}; @@ -2529,7 +2506,7 @@ \item \tcode{is} is an lvalue of the type of some class template specialization \tcode{basic_istream}; -\end{enumeratea} +\end{itemize} where \tcode{charT} and \tcode{traits} are constrained according to \ref{strings} and \ref{input.output}. @@ -2596,7 +2573,7 @@ \tcode{d.param(p)} \indextext{\idxcode{param}!random number distribution requirement} & \tcode{void} - & \postconditions \tcode{d.param() == p}. + & \ensures \tcode{d.param() == p}. & no worse than the complexity of \tcode{D(p)} \\ \rowsep \tcode{d(g)} @@ -2667,7 +2644,7 @@ & Writes to \tcode{os} a textual representation for the parameters and the additional internal data of \tcode{x}. - \postconditions The \tcode{os.}\textit{fmtflags} and fill character are unchanged. + \ensures The \tcode{os.}\textit{fmtflags} and fill character are unchanged. & \\ \rowsep \tcode{is >> d} @@ -2688,7 +2665,7 @@ \tcode{charT} and \tcode{traits} were the same as those of \tcode{is}. - \postconditions The \tcode{is.}\textit{fmtflags} are unchanged. + \ensures The \tcode{is.}\textit{fmtflags} are unchanged. & \\ \end{libreqtab4d} @@ -2988,7 +2965,7 @@ defined by values $u$, $d$, $s$, $b$, $t$, $c$, and $\ell$. The state transition is performed as follows: -\begin{enumeratea} +\begin{itemize} \item Concatenate the upper $w-r$ bits of $X_{i-n}$ @@ -2999,7 +2976,7 @@ With $\alpha = a \cdot (Y \bitand 1)$, set $X_i$ to $X_{i+m-n} \xor (Y \rightshift 1) \xor \alpha$. -\end{enumeratea} +\end{itemize} The sequence $X$ is initialized with the help of an initialization multiplier $f$. @@ -3009,7 +2986,7 @@ \indextext{generation algorithm!\idxcode{mersenne_twister_engine}} determines the unsigned integer values $z_1, z_2, z_3, z_4$ as follows, then delivers $z_4$ as its result: -\begin{enumeratea} +\begin{itemize} \item Let $z_1 = X_i \xor \bigl(( X_i \rightshift u ) \bitand d\bigr)$. \item @@ -3018,7 +2995,7 @@ Let $z_3 = z_2 \xor \bigl( (z_2 \leftshift{w} t) \bitand c \bigr)$. \item Let $z_4 = z_3 \xor ( z_3 \rightshift \ell )$. -\end{enumeratea} +\end{itemize} \indexlibrary{\idxcode{mersenne_twister_engine}}% \begin{codeblock} @@ -3165,14 +3142,14 @@ \indextext{\idxcode{subtract_with_carry_engine}!transition algorithm}% \indextext{transition algorithm!\idxcode{subtract_with_carry_engine}} is performed as follows: -\begin{enumeratea} +\begin{itemize} \item Let $Y = X_{i-s} - X_{i-r} - c$. \item Set $X_i$ to $y = Y \bmod m$. Set $c$ to 1 if $Y < 0$, otherwise set $c$ to 0. -\end{enumeratea} +\end{itemize} \begin{note} This algorithm corresponds to a modular linear function @@ -3480,7 +3457,7 @@ The transition and generation algorithms are described in terms of the following integral constants:% -\begin{enumeratea} +\begin{itemize} \item Let $R = \tcode{e.max() - e.min() + 1}$ @@ -3502,7 +3479,7 @@ holds as a result. Otherwise let $n = 1 + \left\lceil w / m \right\rceil$. -\end{enumeratea} +\end{itemize} \begin{note} The relation $w = n_0 w_0 + (n - n_0)(w_0 + 1)$ @@ -3618,7 +3595,7 @@ \indextext{transition algorithm!\idxcode{shuffle_order_engine}} permutes the values produced by $e$. The state transition is performed as follows: -\begin{enumeratea} +\begin{itemize} \item Calculate an integer $j = \left\lfloor \frac{k \cdot (Y - e_{\min})} @@ -3628,7 +3605,7 @@ . \item Set $Y$ to $V_j$ and then set $V_j$ to $\tcode{e()}$. -\end{enumeratea} +\end{itemize} \pnum The generation algorithm% @@ -4129,7 +4106,7 @@ each indexing operator applied to \tcode{begin} is to be taken modulo $n$, and $T(x)$ is defined as $x \xor (x \rightshift 27)$: -\begin{enumeratea} +\begin{itemize} \item By way of initialization, set each element of the range to the value \tcode{0x8b8b8b8b}. @@ -4164,10 +4141,10 @@ \right. \end{eqnarray*} and, in order, - increment $\tcode{begin[}k+p\tcode{]}$ by $r_1$, - increment $\tcode{begin[}k+q\tcode{]}$ by $r_2$, + increment \tcode{begin[$k+p$]} by $r_1$, + increment \tcode{begin[$k+q$]} by $r_2$, and - set \tcode{begin[k]} to $r_2$. + set \tcode{begin[$k$]} to $r_2$. \item Transform the elements of the range again, beginning where the previous step ended: @@ -4184,11 +4161,11 @@ \end{eqnarray*} and, in order, \noindent - update $\tcode{begin[}k+p\tcode{]}$ by xoring it with $r_3$, - update $\tcode{begin[}k+q\tcode{]}$ by xoring it with $r_4$, + update \tcode{begin[$k+p$]} by xoring it with $r_3$, + update \tcode{begin[$k+q$]} by xoring it with $r_4$, and - set $\tcode{begin[}k\tcode{]}$ to $r_4$. -\end{enumeratea} + set \tcode{begin[$k$]} to $r_4$. +\end{itemize} \pnum\throws What and when \tcode{RandomAccessIterator} operations of \tcode{begin} @@ -6076,6 +6053,7 @@ shall each satisfy the \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, + the \grammarterm{id-expression}s \tcode{iterator_traits::value_type} and \tcode{iterator_traits::value_type} shall each denote a type that is convertible to \tcode{double}. @@ -6286,6 +6264,7 @@ shall each satisfy the \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, + the \grammarterm{id-expression}s \tcode{iterator_traits::value_type} and \tcode{iterator_traits::value_type} shall each denote a type that is convertible to \tcode{double}. @@ -6680,7 +6659,7 @@ \rSec2[template.valarray]{Class template \tcode{valarray}} -\rSec3[template.valarray.overview]{Class template \tcode{valarray} overview} +\rSec3[template.valarray.overview]{Overview} \indexlibrary{\idxcode{valarray}}% \begin{codeblock} @@ -6799,7 +6778,7 @@ matrix class nor a field class. However, it is a very useful building block for designing such classes.} -\rSec3[valarray.cons]{\tcode{valarray} constructors} +\rSec3[valarray.cons]{Constructors} \indexlibrary{\idxcode{valarray}!constructor}% \begin{itemdecl} @@ -6936,7 +6915,7 @@ an implementation may return all allocated memory. \end{itemdescr} -\rSec3[valarray.assign]{\tcode{valarray} assignment} +\rSec3[valarray.assign]{Assignment} \indexlibrarymember{operator=}{valarray}% \begin{itemdecl} @@ -6954,7 +6933,7 @@ as if by calling \tcode{resize(v.size())}, before performing the assignment. \pnum -\postconditions \tcode{size() == v.size()}. +\ensures \tcode{size() == v.size()}. \pnum \returns \tcode{*this}. @@ -7022,7 +7001,7 @@ \tcode{valarray}. \end{itemdescr} -\rSec3[valarray.access]{\tcode{valarray} element access} +\rSec3[valarray.access]{Element access} \indexlibrarymember{operator[]}{valarray}% \begin{itemdecl} @@ -7074,7 +7053,7 @@ that array ends, whichever happens first. \end{itemdescr} -\rSec3[valarray.sub]{\tcode{valarray} subset operations} +\rSec3[valarray.sub]{Subset operations} \indexlibrary{\idxcode{operator[]}!\idxcode{valarray}}% \pnum @@ -7240,7 +7219,7 @@ \end{example} \end{itemdescr} -\rSec3[valarray.unary]{\tcode{valarray} unary operators} +\rSec3[valarray.unary]{Unary operators} \indexlibrarymember{operator+}{valarray}% \indexlibrarymember{operator-}{valarray}% @@ -7268,7 +7247,7 @@ applying the indicated operator to the corresponding element of the array. \end{itemdescr} -\rSec3[valarray.cassign]{\tcode{valarray} compound assignment} +\rSec3[valarray.cassign]{Compound assignment} \indexlibrarymember{operator*=}{valarray}% \indexlibrarymember{operator/=}{valarray}% @@ -7364,7 +7343,7 @@ invalidate references or pointers to the elements of the array. \end{itemdescr} -\rSec3[valarray.members]{\tcode{valarray} member functions} +\rSec3[valarray.members]{Member functions} \indexlibrarymember{swap}{valarray}% \begin{itemdecl} @@ -7527,7 +7506,7 @@ \rSec2[valarray.nonmembers]{\tcode{valarray} non-member operations} -\rSec3[valarray.binary]{\tcode{valarray} binary operators} +\rSec3[valarray.binary]{Binary operators} \indexlibrarymember{operator*}{valarray}% \indexlibrarymember{operator/}{valarray}% @@ -7640,7 +7619,7 @@ corresponding element of the array argument and the non-array argument. \end{itemdescr} -\rSec3[valarray.comparison]{\tcode{valarray} logical operators} +\rSec3[valarray.comparison]{Logical operators} \indexlibrarymember{operator==}{valarray}% \indexlibrarymember{operator"!=}{valarray}% @@ -7740,7 +7719,7 @@ indicated operator to the corresponding element of the array and the non-array argument. \end{itemdescr} -\rSec3[valarray.transcend]{\tcode{valarray} transcendentals} +\rSec3[valarray.transcend]{Transcendentals} \indexlibrary{\idxcode{abs}!\idxcode{valarray}}% \indexlibrary{\idxcode{acos}!\idxcode{valarray}}% @@ -7790,7 +7769,7 @@ or which can be unambiguously implicitly converted to type \tcode{T}. \end{itemdescr} -\rSec3[valarray.special]{\tcode{valarray} specialized algorithms} +\rSec3[valarray.special]{Specialized algorithms} \indexlibrarymember{swap}{valarray}% \begin{itemdecl} @@ -7805,7 +7784,7 @@ \rSec2[class.slice]{Class \tcode{slice}} -\rSec3[class.slice.overview]{Class \tcode{slice} overview} +\rSec3[class.slice.overview]{Overview} \indexlibrary{\idxcode{slice}}% \begin{codeblock} @@ -7837,7 +7816,7 @@ Mathematics and Computer Science Division, August, 1988.} -\rSec3[cons.slice]{\tcode{slice} constructors} +\rSec3[cons.slice]{Constructors} \indexlibrary{\idxcode{slice}!constructor}% \begin{itemdecl} @@ -7856,11 +7835,11 @@ \pnum \begin{example} \tcode{slice(3, 8, 2)} -constructs a slice which selects elements 3, 5, 7, ... 17 from an array. +constructs a slice which selects elements $3, 5, 7, \dotsc, 17$ from an array. \end{example} \end{itemdescr} -\rSec3[slice.access]{\tcode{slice} access functions} +\rSec3[slice.access]{Access functions} \indexlibrarymember{start}{slice}% \indexlibrarymember{size}{slice}% \indexlibrarymember{stride}{slice}% @@ -7881,7 +7860,7 @@ \rSec2[template.slice.array]{Class template \tcode{slice_array}} -\rSec3[template.slice.array.overview]{Class template \tcode{slice_array} overview} +\rSec3[template.slice.array.overview]{Overview} \indexlibrary{\idxcode{slice_array}}% \indexlibrarymember{value_type}{slice_array}% @@ -7934,10 +7913,10 @@ For the slice shown, the elements selected from \tcode{a} -are 1, 4, ..., 13. +are $1, 4, \dotsc, 13$. \end{example} -\rSec3[slice.arr.assign]{\tcode{slice_array} assignment} +\rSec3[slice.arr.assign]{Assignment} \indexlibrary{\idxcode{operator=}!\idxcode{slice_array}}% \begin{itemdecl} @@ -7956,7 +7935,7 @@ object refers. \end{itemdescr} -\rSec3[slice.arr.comp.assign]{\tcode{slice_array} compound assignment} +\rSec3[slice.arr.comp.assign]{Compound assignment} \indexlibrarymember{operator*=}{slice_array}% \indexlibrarymember{operator/=}{slice_array}% @@ -7992,7 +7971,7 @@ object refers. \end{itemdescr} -\rSec3[slice.arr.fill]{\tcode{slice_array} fill function} +\rSec3[slice.arr.fill]{Fill function} \indexlibrarymember{operator=}{slice_array}% \begin{itemdecl} @@ -8011,7 +7990,7 @@ \rSec2[class.gslice]{The \tcode{gslice} class} -\rSec3[class.gslice.overview]{The \tcode{gslice} class overview} +\rSec3[class.gslice.overview]{Overview} \indexlibrary{\idxcode{gslice}}% \begin{codeblock} @@ -8119,7 +8098,7 @@ the behavior is undefined. \indextext{undefined}% -\rSec3[gslice.cons]{\tcode{gslice} constructors} +\rSec3[gslice.cons]{Constructors} \indexlibrary{\idxcode{gslice}!constructor}% \begin{itemdecl} @@ -8139,7 +8118,7 @@ in the previous subclause. \end{itemdescr} -\rSec3[gslice.access]{\tcode{gslice} access functions} +\rSec3[gslice.access]{Access functions} \indexlibrarymember{start}{gslice}% \indexlibrarymember{size}{gslice}% @@ -8162,7 +8141,7 @@ \rSec2[template.gslice.array]{Class template \tcode{gslice_array}} -\rSec3[template.gslice.array.overview]{Class template \tcode{gslice_array} overview} +\rSec3[template.gslice.array.overview]{Overview} \indexlibrary{\idxcode{gslice_array}}% \indexlibrarymember{value_type}{gslice_array}% @@ -8217,7 +8196,7 @@ generalized slice of the elements in \tcode{a}. -\rSec3[gslice.array.assign]{\tcode{gslice_array} assignment} +\rSec3[gslice.array.assign]{Assignment} \indexlibrarymember{operator=}{gslice_array}% \begin{itemdecl} @@ -8235,7 +8214,7 @@ refers. \end{itemdescr} -\rSec3[gslice.array.comp.assign]{\tcode{gslice_array} compound assignment} +\rSec3[gslice.array.comp.assign]{Compound assignment} \indexlibrarymember{operator*=}{gslice_array}% \indexlibrarymember{operator/=}{gslice_array}% @@ -8271,7 +8250,7 @@ object refers. \end{itemdescr} -\rSec3[gslice.array.fill]{\tcode{gslice_array} fill function} +\rSec3[gslice.array.fill]{Fill function} \indexlibrarymember{operator=}{gslice_array}% \begin{itemdecl} @@ -8290,7 +8269,7 @@ \rSec2[template.mask.array]{Class template \tcode{mask_array}} -\rSec3[template.mask.array.overview]{Class template \tcode{mask_array} overview} +\rSec3[template.mask.array.overview]{Overview} \indexlibrary{\idxcode{mask_array}}% \indexlibrarymember{value_type}{mask_array}% @@ -8332,20 +8311,13 @@ \pnum It has reference semantics to a subset of an array specified by a boolean mask. -Thus, the expression -\tcode{a[mask] = b;} +Thus, the expression \tcode{a[mask] = b;} has the effect of assigning the elements of -\tcode{b} -to the masked -elements in -\tcode{a} -(those for which the corresponding element -in -\tcode{mask} -is -\tcode{true}.) +\tcode{b} to the masked elements in \tcode{a} +(those for which the corresponding element in +\tcode{mask} is \tcode{true}). -\rSec3[mask.array.assign]{\tcode{mask_array} assignment} +\rSec3[mask.array.assign]{Assignment} \indexlibrarymember{operator=}{mask_array}% \begin{itemdecl} @@ -8361,7 +8333,7 @@ object to which it refers. \end{itemdescr} -\rSec3[mask.array.comp.assign]{\tcode{mask_array} compound assignment} +\rSec3[mask.array.comp.assign]{Compound assignment} \indexlibrarymember{operator*=}{mask_array}% \indexlibrarymember{operator/=}{mask_array}% @@ -8395,7 +8367,7 @@ object to which the mask object refers. \end{itemdescr} -\rSec3[mask.array.fill]{\tcode{mask_array} fill function} +\rSec3[mask.array.fill]{Fill function} \indexlibrarymember{operator=}{mask_array}% \begin{itemdecl} @@ -8414,7 +8386,7 @@ \rSec2[template.indirect.array]{Class template \tcode{indirect_array}} -\rSec3[template.indirect.array.overview]{Class template \tcode{indirect_array} overview} +\rSec3[template.indirect.array.overview]{Overview} \indexlibrary{\idxcode{indirect_array}}% \indexlibrarymember{value_type}{indirect_array}% @@ -8466,7 +8438,7 @@ whose indices appear in \tcode{indirect}. -\rSec3[indirect.array.assign]{\tcode{indirect_array} assignment} +\rSec3[indirect.array.assign]{Assignment} \indexlibrarymember{operator=}{indirect_array}% \begin{itemdecl} @@ -8502,7 +8474,7 @@ \end{example} \end{itemdescr} -\rSec3[indirect.array.comp.assign]{\tcode{indirect_array} compound assignment} +\rSec3[indirect.array.comp.assign]{Compound assignment} \indexlibrarymember{operator*=}{indirect_array}% \indexlibrarymember{operator/=}{indirect_array}% @@ -8546,7 +8518,7 @@ \indextext{undefined} \end{itemdescr} -\rSec3[indirect.array.fill]{\tcode{indirect_array} fill function} +\rSec3[indirect.array.fill]{Fill function} \indexlibrarymember{operator=}{indirect_array}% \begin{itemdecl} @@ -8567,14 +8539,14 @@ \pnum In the \tcode{begin} and \tcode{end} function templates that follow, \unspec{1} -is a type that meets the requirements of a mutable random access -iterator\iref{random.access.iterators} -and of a contiguous iterator\iref{iterator.requirements.general} +is a type that meets the requirements of a mutable +\oldconcept{RandomAccessIterator}\iref{random.access.iterators} +and models \libconcept{ContiguousIterator}\iref{iterator.concept.contiguous}, whose \tcode{value_type} is the template parameter \tcode{T} and whose \tcode{reference} type is \tcode{T\&}. \unspec{2} is a -type that meets the requirements of a constant random access -iterator\iref{random.access.iterators} -and of a contiguous iterator\iref{iterator.requirements.general} +type that meets the requirements of a constant +\oldconcept{RandomAccessIterator} +and models \libconcept{ContiguousIterator}, whose \tcode{value_type} is the template parameter \tcode{T} and whose \tcode{reference} type is \tcode{const T\&}. diff --git a/source/overloading.tex b/source/overloading.tex index 107716f9a8..8fb11504ac 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1964,6 +1964,7 @@ cv-qualification, and value category of the argument and how these are converted to match the corresponding properties of the parameter. +\begin{note} Other properties, such as the lifetime, storage class, alignment, accessibility of the argument, whether the argument is a bit-field, and whether a function is deleted\iref{dcl.fct.def.delete}, are ignored. @@ -1971,6 +1972,7 @@ conversion sequence can be defined for a given argument-parameter pair, the conversion from the argument to the parameter might still be ill-formed in the final analysis. +\end{note} \pnum A @@ -2078,8 +2080,8 @@ to a parameter type, an implicit conversion sequence cannot be formed. \pnum -If several different sequences of conversions exist that each -convert the argument to the parameter type, the implicit +If there are multiple well-formed implicit conversion sequences +converting the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the \defnadj{ambiguous}{conversion sequence}. @@ -2184,7 +2186,7 @@ \rSec4[over.ics.user]{User-defined conversion sequences} \pnum -A user-defined conversion sequence consists of an initial +A \defnadj{user-defined}{conversion sequence} consists of an initial standard conversion sequence followed by a user-defined conversion\iref{class.conv} followed by a second standard conversion sequence. @@ -2264,8 +2266,8 @@ does not constitute a conversion. \pnum -Except for an implicit object parameter, for which see~\ref{over.match.funcs}, a -standard conversion sequence cannot be formed if it requires +Except for an implicit object parameter, for which see~\ref{over.match.funcs}, +an implicit conversion sequence cannot be formed if it requires binding an lvalue reference other than a reference to a non-volatile \tcode{const} type to an rvalue @@ -2281,7 +2283,7 @@ \pnum Other restrictions on binding a reference to a particular argument that are not based on the types of the reference and the argument -do not affect the formation of a standard conversion +do not affect the formation of an implicit conversion sequence, however. \begin{example} A function with an ``lvalue reference to \tcode{int}'' parameter can @@ -2747,8 +2749,7 @@ \begin{itemize} \item -A conversion that does not convert a pointer, -a pointer to member, or \tcode{std::nullptr_t} +A conversion that does not convert a pointer or a pointer to member to \tcode{bool} is better than one that does. @@ -3411,8 +3412,7 @@ uses \tcode{->}. \begin{ncsimplebnf} -postfix-expression \terminal{->} \terminal{\opt{template}} id-expression\\ -postfix-expression \terminal{->} pseudo-destructor-name +postfix-expression \terminal{->} \terminal{\opt{template}} id-expression \end{ncsimplebnf} An expression @@ -3538,10 +3538,12 @@ long double char wchar_t +char8_t char16_t char32_t const char*, std::size_t const wchar_t*, std::size_t +const char8_t*, std::size_t const char16_t*, std::size_t const char32_t*, std::size_t \end{codeblock} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 8b89401d34..e43db6a9d7 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -292,7 +292,7 @@ \topline \lhdr{Attribute} & \rhdr{Value} \\ \rowsep \tcode{assert} & \tcode{201806L} \\ -\tcode{carries_depencency} & \tcode{200809L} \\ +\tcode{carries_dependency} & \tcode{200809L} \\ \tcode{deprecated} & \tcode{201309L} \\ \tcode{ensures} & \tcode{201806L} \\ \tcode{expects} & \tcode{201806L} \\ @@ -810,6 +810,12 @@ \indextext{macro!argument substitution}% \indextext{argument substitution|see{macro, argument substitution}}% +\indextext{__VA_OPT__@\mname{VA_OPT}}% +\begin{bnf} +\nontermdef{va-opt-replacement}\br + \terminal{\mname{VA_OPT} (} \opt{pp-tokens} \terminal{)} +\end{bnf} + \pnum After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. @@ -819,10 +825,10 @@ naming the parameter are replaced by a token sequence determined as follows: \begin{itemize} \item - If the parameter is of the form - \mname{VA_OPT}\tcode{(}\placeholder{content}\tcode{)}, + If the parameter is of the form \grammarterm{va-opt-replacement}, the replacement preprocessing tokens are the - preprocessing token sequence for the corresponding argument. + preprocessing token sequence for the corresponding argument, + as specified below. \item Otherwise, the replacement preprocessing tokens are the preprocessing tokens of corresponding argument after all @@ -850,18 +856,16 @@ \indextext{__VA_OPT__@\mname{VA_OPT}}% The identifier \mname{VA_OPT} shall always occur as part of the preprocessing token sequence -\mname{VA_OPT}\tcode{(}\placeholder{cont\-ent}\tcode{)}, -where \placeholder{content} is -an arbitrary sequence of \grammarterm{preprocessing-token}s -other than \mname{VA_OPT}, -which is terminated by the closing \tcode{)} -and skips intervening pairs of matching left and right parentheses. -If \placeholder{content} would be ill-formed +\grammarterm{va-opt-replacement}; +its closing \tcode{)} is determined by skipping +intervening pairs of matching left and right parentheses +in its \grammarterm{pp-tokens}. +The \grammarterm{pp-tokens} of a \grammarterm{va-opt-replacement} +shall not contain \mname{VA_OPT}. +If the \grammarterm{pp-tokens} would be ill-formed as the replacement list of the current function-like macro, the program is ill-formed. -The preprocessing token sequence -\mname{VA_OPT}\tcode{(}\placeholder{content}\tcode{)} -shall be treated as if it were a parameter, +A \grammarterm{va-opt-replacement} is treated as if it were a parameter, and the preprocessing token sequence for the corresponding argument is defined as follows. If the substitution of \mname{VA_ARGS} as neither an operand @@ -869,7 +873,7 @@ the argument consists of a single placemarker preprocessing token~(\ref{cpp.concat}, \ref{cpp.rescan}). Otherwise, the argument consists of -the results of the expansion of \placeholder{content} +the results of the expansion of the contained \grammarterm{pp-tokens} as the replacement list of the current function-like macro before removal of placemarker tokens, rescanning, and further replacement. \begin{note} @@ -1476,18 +1480,21 @@ \defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep \defnxname{cpp_binary_literals} & \tcode{201304L} \\ \rowsep \defnxname{cpp_capture_star_this} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep +\defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep \defnxname{cpp_constexpr} & \tcode{201603L} \\ \rowsep \defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep \defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep \defnxname{cpp_deduction_guides} & \tcode{201703L} \\ \rowsep \defnxname{cpp_delegating_constructors} & \tcode{200604L} \\ \rowsep \defnxname{cpp_enumerator_attributes} & \tcode{201411L} \\ \rowsep -\defnxname{cpp_explicit_bool} & \tcode{201806L} \\ \rowsep \defnxname{cpp_fold_expressions} & \tcode{201603L} \\ \rowsep \defnxname{cpp_generic_lambdas} & \tcode{201304L} \\ \rowsep \defnxname{cpp_guaranteed_copy_elision} & \tcode{201606L} \\ \rowsep \defnxname{cpp_hex_float} & \tcode{201603L} \\ \rowsep \defnxname{cpp_if_constexpr} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_impl_destroying_delete} & \tcode{201806L} \\ \rowsep +\defnxname{cpp_impl_three_way_comparison} & \tcode{201711L} \\ \rowsep \defnxname{cpp_inheriting_constructors} & \tcode{201511L} \\ \rowsep \defnxname{cpp_init_captures} & \tcode{201304L} \\ \rowsep \defnxname{cpp_initializer_lists} & \tcode{200806L} \\ \rowsep diff --git a/source/ranges.tex b/source/ranges.tex new file mode 100644 index 0000000000..0bc5751273 --- /dev/null +++ b/source/ranges.tex @@ -0,0 +1,5120 @@ +%!TEX root = std.tex +\rSec0[ranges]{Ranges library} + +\rSec1[ranges.general]{General} + +\pnum +This clause describes components for dealing with ranges of elements. + +\pnum +The following subclauses describe +range and view requirements, and +components for +range primitives +as summarized in \tref{range.summary}. + +\begin{libsumtab}{Ranges library summary}{tab:range.summary} + \ref{range.access} & Range access & \tcode{} \\ + \ref{range.prim} & Range primitives & \\ + \ref{range.req} & Requirements & \\ + \ref{range.utility} & Range utilities & \\ + \ref{range.adaptors} & Range adaptors & \\ +\end{libsumtab} + +\pnum +Several places in this clause use the expression \tcode{\placeholdernc{DECAY_COPY}(x)} +with semantics as defined in \ref{thread.decaycopy}. + + +\rSec1[ranges.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxhdr{ranges}}% +\begin{codeblock} +#include +#include + +namespace std::ranges { + inline namespace @\unspec@ { + // \ref{range.access}, range access + inline constexpr @\unspec@ begin = @\unspec@; + inline constexpr @\unspec@ end = @\unspec@; + inline constexpr @\unspec@ cbegin = @\unspec@; + inline constexpr @\unspec@ cend = @\unspec@; + inline constexpr @\unspec@ rbegin = @\unspec@; + inline constexpr @\unspec@ rend = @\unspec@; + inline constexpr @\unspec@ crbegin = @\unspec@; + inline constexpr @\unspec@ crend = @\unspec@; + + // \ref{range.prim}, range primitives + inline constexpr @\unspec@ size = @\unspec@; + inline constexpr @\unspec@ empty = @\unspec@; + inline constexpr @\unspec@ data = @\unspec@; + inline constexpr @\unspec@ cdata = @\unspec@; + } + + // \ref{range.range}, ranges + template + using iterator_t = decltype(ranges::begin(declval())); + + template + using sentinel_t = decltype(ranges::end(declval())); + + template<@\placeholder{fowarding-range}@ R> + using safe_iterator_t = iterator_t; + + template + concept Range = @\seebelow@; + + // \ref{range.sized}, sized ranges + template + inline constexpr bool disable_sized_range = false; + + template + concept SizedRange = @\seebelow@; + + // \ref{range.view}, views + template + inline constexpr bool enable_view = @\seebelow@; + + struct view_base { }; + + template + concept View = @\seebelow@; + + // \ref{range.refinements}, common range refinements + template + concept OutputRange = @\seebelow@; + + template + concept InputRange = @\seebelow@; + + template + concept ForwardRange = @\seebelow@; + + template + concept BidirectionalRange = @\seebelow@; + + template + concept RandomAccessRange = @\seebelow@; + + template + concept ContiguousRange = @\seebelow@; + + template + concept CommonRange = @\seebelow@; + + template + concept ViewableRange = @\seebelow@; + + // \ref{view.interface}, class template \tcode{view_interface} + template + requires is_class_v + class view_interface; + + // \ref{range.subrange}, sub-ranges + enum class subrange_kind : bool { unsized, sized }; + + template S = I, subrange_kind K = @\seebelow@> + requires (K == subrange_kind::sized || !SizedSentinel) + class subrange; + + template<@\placeholder{forwarding-range}@ R> + using safe_subrange_t = subrange>; + + // \ref{range.all}, all view + namespace view { inline constexpr @\unspec@ all = @\unspec@; } + + template + using all_view = decltype(view::all(declval())); + + // \ref{range.filter}, filter view + template> Pred> + requires View + class filter_view; + + namespace view { inline constexpr @\unspec@ filter = @\unspec@; } + + // \ref{range.transform}, transform view + template + requires View && is_object_v && + RegularInvocable>> + class transform_view; + + namespace view { inline constexpr @\unspec@ transform = @\unspec@; } + + // \ref{range.iota}, iota view + template + requires @\placeholder{weakly-equality-comparable-with}@ + class iota_view; + + namespace view { inline constexpr @\unspec@ iota = @\unspec@; } + + // \ref{range.take}, take view + template class take_view; + + namespace view { inline constexpr @\unspec@ take = @\unspec@; } + + // \ref{range.join}, join view + template + requires View && InputRange>> && + (is_reference_v>> || + View>>) + class join_view; + + namespace view { inline constexpr @\unspec@ join = @\unspec@; } + + // \ref{range.empty}, empty view + template + requires is_object_v + class empty_view; + + namespace view { + template + inline constexpr empty_view empty {}; + } + + // \ref{range.single}, single view + template + requires is_object_v + class single_view; + + namespace view { inline constexpr @\unspec@ single = @\unspec@; } + + // \ref{range.split}, split view + template + concept @\placeholder{tiny-range}@ = @\seebelow@; // \expos + + template + requires View && View && + IndirectlyComparable, iterator_t, ranges::equal_to<>> && + (ForwardRange || @\placeholder{tiny-range}@) + class split_view; + + namespace view { inline constexpr @\unspec@ split = @\unspec@; } + + // \ref{range.counted}, counted view + namespace view { inline constexpr @\unspec@ counted = @\unspec@; } + + // \ref{range.common}, common view + template + requires (!CommonRange) + class common_view; + + namespace view { inline constexpr @\unspec@ common = @\unspec@; } + + // \ref{range.reverse}, reverse view + template + requires BidirectionalRange + class reverse_view; + + namespace view { inline constexpr @\unspec@ reverse = @\unspec@; } +} + +namespace std { + namespace view = ranges::view; + + template + struct tuple_size> + : integral_constant {}; + template + struct tuple_element<0, ranges::subrange> { + using type = I; + }; + template + struct tuple_element<1, ranges::subrange> { + using type = S; + }; +} +\end{codeblock} + +\rSec1[range.access]{Range access} + +\pnum +In addition to being available via inclusion of the \tcode{} +header, the customization point objects in \ref{range.access} are +available when \tcode{} is included. + +\rSec2[range.access.begin]{\tcode{ranges::begin}} +\pnum +The name \tcode{ranges::begin} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::\brk{}begin(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + \tcode{E + 0} if \tcode{E} is an lvalue of array type\iref{basic.compound}. + +\item + Otherwise, if \tcode{E} is an lvalue, + \tcode{\placeholdernc{DECAY_COPY}(E.begin())} + if it is a valid expression and its type \tcode{I} models \tcode{Iterator}. + +\item + Otherwise, \tcode{\placeholdernc{DECAY_COPY}(begin(E))} if it is a + valid expression and its type \tcode{I} models \tcode{Iterator} with overload + resolution performed in a context that includes the declarations: + \begin{codeblock} + template void begin(T&&) = delete; + template void begin(initializer_list&&) = delete; + \end{codeblock} + + and does not include a declaration of \tcode{ranges::begin}. + +\item + Otherwise, \tcode{ranges::begin(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::begin(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::begin(E)} is a valid expression, its type models +\tcode{Iterator}. +\end{note} + +\rSec2[range.access.end]{\tcode{ranges::end}} +\pnum +The name \tcode{ranges::end} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::end(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + \tcode{E + extent_v} if \tcode{E} is an lvalue of array + type\iref{basic.compound} \tcode{T}. + +\item + Otherwise, if \tcode{E} is an lvalue, + \tcode{\placeholdernc{DECAY_COPY}(E.end())} + if it is a valid expression and its type \tcode{S} models + \tcode{Sentinel}. + +\item + Otherwise, \tcode{\placeholdernc{DECAY_COPY}(end(E))} if it is a valid + expression and its type \tcode{S} models + \tcode{Sentinel} with overload + resolution performed in a context that includes the declarations: + \begin{codeblock} + template void end(T&&) = delete; + template void end(initializer_list&&) = delete; + \end{codeblock} + + and does not include a declaration of \tcode{ranges::end}. + +\item + Otherwise, \tcode{ranges::end(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::end(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::end(E)} is a valid expression, +the types \tcode{S} and \tcode{I} of +\tcode{ranges::end(E)} and \tcode{ranges::begin(E)} +model \libconcept{Sentinel}. +\end{note} + +\rSec2[range.access.cbegin]{\tcode{ranges::cbegin}} +\pnum +The name \tcode{ranges::cbegin} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::\brk{}cbegin(E)} for some subexpression \tcode{E} of type \tcode{T} +is expression-equivalent to: +\begin{itemize} +\item \tcode{ranges::begin(static_cast(E))} if \tcode{E} is an lvalue. +\item Otherwise, \tcode{ranges::begin(static_cast(E))}. +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::cbegin(E)} is a valid expression, its type models +\tcode{Iterator}. +\end{note} + +\rSec2[range.access.cend]{\tcode{ranges::cend}} +\pnum +The name \tcode{ranges::cend} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::cend(E)} for some subexpression \tcode{E} of type \tcode{T} +is expression-equivalent to: + +\begin{itemize} +\item \tcode{ranges::end(static_cast(E))} if \tcode{E} is an lvalue. +\item Otherwise, \tcode{ranges::end(static_cast(E))}. +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::cend(E)} is a valid expression, +the types \tcode{S} and \tcode{I} of +\tcode{ranges::cend(E)} and \tcode{ranges::cbegin(E)} +model \libconcept{Sentinel}. +\end{note} + +\rSec2[range.access.rbegin]{\tcode{ranges::rbegin}} +\pnum +The name \tcode{ranges::rbegin} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::\brk{}rbegin(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + If \tcode{E} is an lvalue, \tcode{\placeholdernc{DECAY_COPY}(E.rbegin())} + if it is a valid expression and its type \tcode{I} models \tcode{Iterator}. + +\item + Otherwise, \tcode{\placeholdernc{DECAY_COPY}(rbegin(E))} if it is a valid + expression and its type \tcode{I} models \tcode{Iterator} with overload + resolution performed in a context that includes the declaration: + \begin{codeblock} + template void rbegin(T&&) = delete; + \end{codeblock} + + and does not include a declaration of \tcode{ranges::rbegin}. + +\item + Otherwise, \tcode{make_reverse_iterator(ranges::end(E))} if both + \tcode{ranges::begin(E)} and \tcode{ranges::end(\brk{}E)} are valid + expressions of the same type \tcode{I} which models + \libconcept{BidirectionalIterator}\iref{iterator.concept.bidir}. + +\item + Otherwise, \tcode{ranges::rbegin(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::rbegin(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::rbegin(E)} is a valid expression, its type models +\tcode{Iterator}. +\end{note} + +\rSec2[range.access.rend]{\tcode{ranges::rend}} +\pnum +The name \tcode{ranges::rend} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::rend(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + If \tcode{E} is an lvalue, \tcode{\placeholdernc{DECAY_COPY}(E.rend())} + if it is a valid expression and its type \tcode{S} models + \tcode{Sentinel<\brk{}decltype(ranges::rbegin(E))>}. + +\item + Otherwise, \tcode{\placeholdernc{DECAY_COPY}(rend(E))} if it is a valid + expression and its type \tcode{S} models + \tcode{Sentinel} with overload + resolution performed in a context that includes the declaration: + \begin{codeblock} + template void rend(T&&) = delete; + \end{codeblock} + + and does not include a declaration of \tcode{ranges::rend}. + +\item + Otherwise, \tcode{make_reverse_iterator(ranges::begin(E))} if both + \tcode{ranges::begin(E)} and \tcode{ranges::\brk{}end(E)} are valid + expressions of the same type \tcode{I} which models + \tcode{BidirectionalIterator}\iref{iterator.concept.bidir}. + +\item + Otherwise, \tcode{ranges::rend(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::rend(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::rend(E)} is a valid expression, +the types \tcode{S} and \tcode{I} of +\tcode{ranges::rend(E)} and \tcode{ranges::rbegin(E)} +model \libconcept{Sentinel}. +\end{note} + +\rSec2[range.access.crbegin]{\tcode{ranges::crbegin}} +\pnum +The name \tcode{ranges::crbegin} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::\brk{}crbegin(E)} for some subexpression \tcode{E} of type +\tcode{T} is expression-equivalent to: +\begin{itemize} +\item \tcode{ranges::\brk{}rbegin(static_cast(E))} if \tcode{E} is + an lvalue. +\item Otherwise, \tcode{ranges::rbegin(static_cast(E))}. +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::crbegin(E)} is a valid expression, its +type models \tcode{Iterator}. +\end{note} + +\rSec2[range.access.crend]{\tcode{ranges::crend}} +\pnum +The name \tcode{ranges::crend} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::\brk{}crend(E)} for some subexpression \tcode{E} of type \tcode{T} +is expression-equivalent to: +\begin{itemize} +\item \tcode{ranges::rend(static_cast(E))} if \tcode{E} is an lvalue. + +\item Otherwise, \tcode{ranges::rend(static_cast(E))}. +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::crend(E)} is a valid expression, +the types \tcode{S} and \tcode{I} of +\tcode{ranges::crend(E)} and \tcode{ranges::crbegin(E)} +model \libconcept{Sentinel}. +\end{note} + +\rSec1[range.prim]{Range primitives} + +\pnum +In addition to being available via inclusion of the \tcode{} header, +the customization point objects in \ref{range.prim} are available +when \tcode{} is included. + +\rSec2[range.prim.size]{\tcode{size}} +\pnum +The name \tcode{size} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::size(E)} for some subexpression \tcode{E} with type +\tcode{T} is expression-equivalent to: + +\begin{itemize} +\item + \tcode{\placeholdernc{DECAY_COPY}(extent_v)} if \tcode{T} is an array + type\iref{basic.compound}. + +\item + Otherwise, if + \tcode{disable_sized_range>}\iref{range.sized} + is \tcode{false}: + \begin{itemize} + \item + \tcode{\placeholdernc{DECAY_COPY}(E.size())} + if it is a valid expression and its type \tcode{I} + models \libconcept{Integral}. + + \item + Otherwise, \tcode{\placeholdernc{DECAY_COPY}(size(E))} + if it is a valid expression and its type \tcode{I} + models \libconcept{Integral} + with overload resolution performed in a context that includes + the declaration: + \begin{codeblock} + template void size(T&&) = delete; + \end{codeblock} + + and does not include a declaration of \tcode{ranges::size}. + \end{itemize} + +\item + Otherwise, \tcode{(ranges::end(E) - ranges::begin(E))} + if it is a valid expression and + the types \tcode{I} and \tcode{S} of \tcode{ranges::begin(E)} and + \tcode{ranges::end(E)} model + \tcode{SizedSentinel}\iref{iterator.concept.sizedsentinel} and + \tcode{Forward\-Iterator}. + However, \tcode{E} is evaluated only once. + +\item + Otherwise, \tcode{ranges::size(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::size(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::size(E)} is a valid expression, its +type models \libconcept{Integral}. +\end{note} + +\rSec2[range.prim.empty]{\tcode{empty}} +\pnum +The name \tcode{empty} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::empty(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + \tcode{bool((E).empty())} if it is a valid expression. + +\item + Otherwise, \tcode{(ranges::size(E) == 0)} if it is a valid expression. + +\item + Otherwise, \tcode{EQ}, where \tcode{EQ} is + \tcode{bool(ranges::begin(E) == ranges::end(E))} + except that \tcode{E} is only evaluated once, + if \tcode{EQ} is a valid expression and + the type of \tcode{ranges::begin(E)} models \libconcept{ForwardIterator}. + +\item + Otherwise, \tcode{ranges::empty(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::empty(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::empty(E)} is a valid expression, +it has type \tcode{bool}. +\end{note} + +\rSec2[range.prim.data]{\tcode{data}} +\pnum +The name \tcode{data} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::data(E)} for some subexpression \tcode{E} is +expression-equivalent to: + +\begin{itemize} +\item + If \tcode{E} is an lvalue, \tcode{\placeholdernc{DECAY_COPY}(E.data())} + if it is a valid expression of pointer to object type. + +\item + Otherwise, if \tcode{ranges::begin(E)} is a valid expression whose type models + \tcode{ContiguousIterator}, + \begin{codeblock} + ranges::begin(E) == ranges::end(E) ? nullptr : addressof(*ranges::begin(E)) + \end{codeblock} + + except that \tcode{E} is evaluated only once. + +\item + Otherwise, \tcode{ranges::data(E)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::data(E)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::data(E)} is a valid expression, it +has pointer to object type. +\end{note} + +\rSec2[range.prim.cdata]{\tcode{cdata}} +\pnum +The name \tcode{cdata} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::cdata(E)} for some subexpression \tcode{E} of type \tcode{T} +is expression-equivalent to: +\begin{itemize} +\item \tcode{ranges::data(static_cast(E))} if \tcode{E} is an lvalue. + +\item Otherwise, \tcode{ranges::data(static_cast(E))}. +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::cdata(E)} is a valid expression, it +has pointer to object type. +\end{note} + +\rSec1[range.req]{Range requirements} + +\rSec2[range.req.general]{General} + +\pnum +Ranges are an abstraction that allow a \Cpp{} program +to operate on elements of data structures uniformly. +Calling \tcode{ranges::begin} on a range returns an object +whose type models \libconcept{Iterator}\iref{iterator.concept.iterator}. +Calling \tcode{ranges::end} on a range returns an object whose type \tcode{S}, +together with the type \tcode{I} of the object returned by \tcode{ranges::begin}, +models \libconcept{Sentinel}. +The library formalizes the interfaces, semantics, and complexity of ranges +to enable algorithms and range adaptors that work efficiently +on different types of sequences. + +\pnum +The \libconcept{Range} concept requires that +\tcode{ranges::begin} and \tcode{ranges::end} +return an iterator and a sentinel, respectively. +The \libconcept{SizedRange} concept refines \libconcept{Range} with +the requirement that the number of elements in the range can be determined +in constant time using the \tcode{ranges::size} function. +The \tcode{View} concept specifies requirements on a \libconcept{Range} type +with constant-time copy and assign operations. + +\pnum +Several refinements of \libconcept{Range} group requirements +that arise frequently in concepts and algorithms. +Common ranges are ranges for which +\tcode{ranges::begin} and \tcode{ranges::end} +return objects of the same type. +Random access ranges are ranges for which \tcode{ranges::begin} +returns a type that models +\libconcept{RandomAccessIterator}\iref{iterator.concept.random.access}. +(Contiguous, bidirectional, forward, input, and output ranges +are defined similarly.) +Viewable ranges can be converted to views. + +\rSec2[range.range]{Ranges} + +\pnum +The \libconcept{Range} concept defines the requirements of a type that allows +iteration over its elements by providing an iterator and sentinel +that denote the elements of the range. + +\indexlibrary{\idxcode{Range}}% +\begin{itemdecl} +template + concept @\placeholder{range-impl}@ = // \expos + requires(T&& t) { + ranges::begin(std::forward(t)); // sometimes equality-preserving (see below) + ranges::end(std::forward(t)); + }; + +template + concept Range = @\placeholdernc{range-impl}@; + +template + concept @\placeholder{forwarding-range}@ = // \expos + Range && @\placeholder{range-impl}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The required expressions +\tcode{ranges::begin(std::forward(t))} +and +\tcode{ranges::end(std::forward<\brk{}T>(t))} +of the \tcode{\placeholder{range-impl}} concept +do not require implicit expression variations\iref{concepts.equality}. + +\pnum +Given an expression \tcode{E} such that \tcode{decltype((E))} is \tcode{T}, +\tcode{T} models \tcode{\placeholder{range-impl}} only if + +\begin{itemize} +\item \range{ranges::begin(E)}{ranges::end(E)} + denotes a range\iref{iterator.requirements.general}, + +\item both +\tcode{ranges::begin(E)} +and +\tcode{ranges::end(E)} +are amortized constant time and non-modifying, and + +\item if the type of \tcode{ranges::begin(E)} models +\libconcept{ForwardIterator}, \tcode{ranges::begin(E)} is equality-preserving. +\end{itemize} + +\pnum +\begin{note} +Equality preservation of both \tcode{ranges::begin} and +\tcode{ranges::end} enables passing a \libconcept{Range} whose iterator +type models \libconcept{ForwardIterator} to multiple +algorithms and making multiple passes over the range by repeated calls to +\tcode{ranges::begin} and \tcode{ranges::end}. +Since \tcode{ranges::begin} is not required to be equality-preserving +when the return type does not model \libconcept{ForwardIterator}, repeated calls +might not return equal values or might not be well-defined; +\tcode{ranges::begin} should be called at most once for such a range. +\end{note} + +\pnum +Given an expression \tcode{E} such that \tcode{decltype((E))} is \tcode{T} +and an lvalue \tcode{t} that denotes the same object as \tcode{E}, +\tcode{T} models \tcode{\placeholdernc{forwarding-range}} only if +\begin{itemize} +\item \tcode{ranges::begin(E)} and \tcode{ranges::begin(t)} + are expression-equivalent, +\item \tcode{ranges::end(E)} and \tcode{ranges::end(t)} + are expression-equivalent, and +\item the validity of iterators obtained from the object denoted + by \tcode{E} is not tied to the lifetime of that object. +\end{itemize} + +\pnum +\begin{note} +Since the validity of iterators is not tied to the lifetime of +an object whose type models \tcode{\placeholdernc{forwarding-range}}, +a function can accept arguments of such a type by value and +return iterators obtained from it without danger of dangling. +\end{note} + +\pnum +\begin{example} +Specializations of class template \tcode{subrange}\iref{range.subrange} +model \tcode{\placeholdernc{forwarding-range}}. \tcode{subrange} provides +non-member rvalue overloads of \tcode{begin} and \tcode{end} with the same +semantics as its member lvalue overloads, and \tcode{subrange}'s iterators +- since they are ``borrowed'' from some other range - +do not have validity tied to the lifetime of a \tcode{subrange} object. +\end{example} +\end{itemdescr} + +\rSec2[range.sized]{Sized ranges} + +\pnum +The \libconcept{SizedRange} concept specifies the requirements +of a \libconcept{Range} type that knows its size in constant time with the +\tcode{size} function. + +\indexlibrary{\idxcode{SizedRange}}% +\begin{itemdecl} +template + concept SizedRange = + Range && + !disable_sized_range> && + requires(T& t) { ranges::size(t); }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given an lvalue \tcode{t} of type \tcode{remove_reference_t}, \tcode{T} +models \libconcept{SizedRange} only if + +\begin{itemize} +\item \tcode{ranges::size(t)} is \bigoh{1}, does not modify \tcode{t}, +and is equal to \tcode{ranges::distance(t)}, and + +\item if \tcode{iterator_t} models \libconcept{ForwardIterator}, +\tcode{ranges::size(t)} is well-defined regardless of the evaluation of +\tcode{ranges::begin(t)}. +\begin{note} +\tcode{ranges::size(t)} is otherwise not required to be +well-defined after evaluating \tcode{ranges::begin(t)}. +For example, \tcode{ranges::size(t)} might be well-defined +for a \libconcept{SizedRange} whose iterator type +does not model \libconcept{ForwardIterator} +only if evaluated before the first call to \tcode{ranges::begin(t)}. +\end{note} +\end{itemize} + +\pnum +\begin{note} +The complexity requirement for the evaluation of \tcode{ranges::size} +is non-amortized, unlike the case for the complexity of the evaluations of +\tcode{ranges::begin} and \tcode{ranges::end} in the \tcode{Range} concept. +\end{note} + +\pnum +\begin{note} +\tcode{disable_sized_range} allows use of range types with the library +that satisfy but do not in fact model \libconcept{SizedRange}. +\end{note} +\end{itemdescr} + +\rSec2[range.view]{Views} + +\pnum +The \tcode{View} concept specifies the requirements of a \libconcept{Range} type +that has constant time copy, move, and assignment operators; that is, the cost of +these operations is not proportional to the number of elements in the +\tcode{View}. + +\pnum +\begin{example} +Examples of \tcode{View}s are: + +\begin{itemize} +\item A \libconcept{Range} type that wraps a pair of iterators. + +\item A \libconcept{Range} type that holds its elements by \tcode{shared_ptr} +and shares ownership with all its copies. + +\item A \libconcept{Range} type that generates its elements on demand. +\end{itemize} + +Most containers\iref{containers} are not views since +copying the container copies the elements, +which cannot be done in constant time. +\end{example} + +\indexlibrary{\idxcode{enable_view}}% +\indexlibrary{\idxcode{View}}% +\begin{itemdecl} +template + inline constexpr bool enable_view = @\seebelow@; + +template + concept View = + Range && Semiregular && enable_view; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Since the difference between \libconcept{Range} and \libconcept{View} is largely +semantic, the two are differentiated with the help of \tcode{enable_view}. + +\pnum +For a type \tcode{T}, the default value of \tcode{enable_view} is: +\begin{itemize} + +\item If \tcode{DerivedFrom} is \tcode{true}, \tcode{true}. +\item Otherwise, if \tcode{T} is a specialization of class template + \tcode{initializer_list}\iref{support.initlist}, + \tcode{set}\iref{set}, + \tcode{multiset}\iref{multiset}, + \tcode{unordered_set}\iref{unord.set}, + \tcode{unordered_multiset}\iref{unord.multiset}, or + \tcode{match_results}\iref{re.results}, \tcode{false}. +\item Otherwise, if both \tcode{T} and \tcode{const T} model \libconcept{Range} + and \tcode{iter_reference_t{>}} is not the same type as + \tcode{iter_reference_t{>}}, + \tcode{false}. + \begin{note} + Deep \tcode{const}-ness implies element ownership, + whereas shallow \tcode{const}-ness implies reference semantics. + \end{note} +\item Otherwise, \tcode{true}. +\end{itemize} + +\pnum +Pursuant to \ref{namespace.std}, users may specialize \tcode{enable_view} +to \tcode{true} for types which model \libconcept{View}, +and \tcode{false} for types which do not. +\end{itemdescr} + +\rSec2[range.refinements]{Common range refinements} + +\pnum +The \tcode{OutputRange} concept specifies requirements of a +\libconcept{Range} type for which \tcode{ranges::begin} returns +a model of \tcode{OutputIterator}\iref{iterator.concept.output}. +\tcode{InputRange}, \tcode{ForwardRange}, \tcode{BidirectionalRange}, +and \tcode{RandomAccessRange} are defined similarly. + +\indexlibrary{\idxcode{OutputRange}}% +\indexlibrary{\idxcode{InputRange}}% +\indexlibrary{\idxcode{ForwardRange}}% +\indexlibrary{\idxcode{BidirectionalRange}}% +\indexlibrary{\idxcode{RandomAccessRange}}% +\begin{itemdecl} +template + concept OutputRange = + Range && OutputIterator, T>; + +template + concept InputRange = + Range && InputIterator>; + +template + concept ForwardRange = + InputRange && ForwardIterator>; + +template + concept BidirectionalRange = + ForwardRange && BidirectionalIterator>; + +template + concept RandomAccessRange = + BidirectionalRange && RandomAccessIterator>; +\end{itemdecl} + +\pnum +\tcode{ContiguousRange} additionally requires that +the \tcode{ranges::data} customization point\iref{range.prim.data} +is usable with the range. + +\indexlibrary{\idxcode{ContiguousRange}}% +\begin{itemdecl} +template + concept ContiguousRange = + RandomAccessRange && ContiguousIterator> && + requires(T& t) { + { ranges::data(t) } -> Same>>>; + }; +\end{itemdecl} + +\pnum +The \tcode{CommonRange} concept specifies requirements of +a \libconcept{Range} type for which \tcode{ranges::begin} and +\tcode{ranges::end} return objects of the same type. +\begin{example} +The standard containers\iref{containers} model \tcode{CommonRange}. +\end{example} + +\indexlibrary{\idxcode{CommonRange}}% +\begin{itemdecl} +template + concept CommonRange = + Range && Same, sentinel_t>; +\end{itemdecl} + +\pnum +The \libconcept{ViewableRange} concept specifies the requirements of a +\libconcept{Range} type that can be converted to a \libconcept{View} safely. + +\indexlibrary{\idxcode{ViewableRange}}% +\begin{itemdecl} +template + concept ViewableRange = + Range && (@\placeholder{forwarding-range}@ || View>); +\end{itemdecl} + +\rSec1[range.utility]{Range utilities} + +\pnum +The components in this subclause are general utilities for representing and +manipulating ranges. + +\rSec2[range.utility.helpers]{Helper concepts} + +\pnum +Many of the types in this subclause are specified in terms of +the following exposition-only concepts: + +\begin{codeblock} +template + concept @\placeholder{simple-view}@ = + View && Range && + Same, iterator_t> && + Same, sentinel_t>; + +template + concept @\placeholder{has-arrow}@ = + is_pointer_v || requires(I i) { i.operator->(); }; + +template + concept @\placeholder{not-same-as}@ = + !Same, remove_cvref_t>; +\end{codeblock} + +\rSec2[view.interface]{View interface} + +\pnum +The class template \tcode{view_interface} is a helper for defining +\tcode{View}-like types that offer a container-like interface. It is +parameterized with the type that is derived from it. + +\indexlibrary{\idxcode{view_interface}}% +\begin{codeblock} +namespace std::ranges { + template + struct @\placeholdernc{range-common-iterator-impl}@ { // \expos + using type = common_iterator, sentinel_t>; + }; + template + struct @\placeholdernc{range-common-iterator-impl}@ { // \expos + using type = iterator_t; + }; + template + using @\placeholdernc{range-common-iterator}@ = // \expos + typename @\placeholdernc{range-common-iterator-impl}@::type; + + template + requires is_class_v && Same> + class view_interface : public view_base { + private: + constexpr D& derived() noexcept { // \expos + return static_cast(*this); + } + constexpr const D& derived() const noexcept { // \expos + return static_cast(*this); + } + public: + constexpr bool empty() requires ForwardRange { + return ranges::begin(derived()) == ranges::end(derived()); + } + constexpr bool empty() const requires ForwardRange { + return ranges::begin(derived()) == ranges::end(derived()); + } + + constexpr explicit operator bool() + requires requires { ranges::empty(derived()); } { + return !ranges::empty(derived()); + } + constexpr explicit operator bool() const + requires requires { ranges::empty(derived()); } { + return !ranges::empty(derived()); + } + + constexpr auto data() requires ContiguousIterator> { + return ranges::empty(derived()) ? nullptr : addressof(*ranges::begin(derived())); + } + constexpr auto data() const + requires Range && ContiguousIterator> { + return ranges::empty(derived()) ? nullptr : addressof(*ranges::begin(derived())); + } + + constexpr auto size() requires ForwardRange && + SizedSentinel, iterator_t> { + return ranges::end(derived()) - ranges::begin(derived()); + } + constexpr auto size() const requires ForwardRange && + SizedSentinel, iterator_t> { + return ranges::end(derived()) - ranges::begin(derived()); + } + + constexpr decltype(auto) front() requires ForwardRange; + constexpr decltype(auto) front() const requires ForwardRange; + + constexpr decltype(auto) back() requires BidirectionalRange && CommonRange; + constexpr decltype(auto) back() const + requires BidirectionalRange && CommonRange; + + template + constexpr decltype(auto) operator[](iter_difference_t> n) { + return ranges::begin(derived())[n]; + } + template + constexpr decltype(auto) operator[](iter_difference_t> n) const { + return ranges::begin(derived())[n]; + } + }; +} +\end{codeblock} + +\pnum +The template parameter \tcode{D} for \tcode{view_interface} may be an +incomplete type. Before any member of the resulting specialization of +\tcode{view_interface} other than special member functions +is referenced, \tcode{D} shall be complete, and +model both \libconcept{DerivedFrom>} and \libconcept{View}. + +\rSec3[view.interface.members]{Members} + +\indexlibrary{\idxcode{view_interface}!\idxcode{front}}% +\begin{itemdecl} +constexpr decltype(auto) front() requires ForwardRange; +constexpr decltype(auto) front() const requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects \tcode{!empty()}. + +\pnum +\effects Equivalent to: \tcode{return *ranges::begin(derived());} +\end{itemdescr} + +\indexlibrary{\idxcode{view_interface}!\idxcode{back}}% +\begin{itemdecl} +constexpr decltype(auto) back() requires BidirectionalRange && CommonRange; +constexpr decltype(auto) back() const + requires BidirectionalRange && CommonRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects \tcode{!empty()}. + +\pnum +\effects Equivalent to: \tcode{return *ranges::prev(ranges::end(derived()));} +\end{itemdescr} + +\rSec2[range.subrange]{Sub-ranges} + +\pnum +The \tcode{subrange} class template combines together an +iterator and a sentinel into a single object that models the +\libconcept{View} concept. Additionally, it models the +\libconcept{SizedRange} concept when the final template parameter is +\tcode{subrange_kind::sized}. + +\indexlibrary{\idxcode{subrange}}% +\begin{codeblock} +namespace std::ranges { + template + concept @\placeholdernc{pair-like}@ = // \expos + !is_reference_v && requires(T t) { + typename tuple_size::type; // ensures tuple_size is complete + requires DerivedFrom, integral_constant>; + typename tuple_element_t<0, remove_const_t>; + typename tuple_element_t<1, remove_const_t>; + { get<0>(t) } -> const tuple_element_t<0, T>&; + { get<1>(t) } -> const tuple_element_t<1, T>&; + }; + + template + concept @\placeholdernc{pair-like-convertible-to}@ = // \expos + !Range && @\placeholder{pair-like}@> && + requires(T&& t) { + { get<0>(std::forward(t)) } -> ConvertibleTo; + { get<1>(std::forward(t)) } -> ConvertibleTo; + }; + + template + concept @\placeholdernc{pair-like-convertible-from}@ = // \expos + !Range && @\placeholdernc{pair-like}@ && Constructible; + + template + concept @\placeholdernc{iterator-sentinel-pair}@ = // \expos + !Range && @\placeholdernc{pair-like}@ && + Sentinel, tuple_element_t<0, T>>; + + template S = I, subrange_kind K = + SizedSentinel ? subrange_kind::sized : subrange_kind::unsized> + requires (K == subrange_kind::sized || !SizedSentinel) + class subrange : public view_interface> { + private: + static constexpr bool StoreSize = // \expos + K == subrange_kind::sized && !SizedSentinel; + I begin_ = I(); // \expos + S end_ = S(); // \expos + iter_difference_t size_ = 0; // \expos; present only + // when \tcode{StoreSize} is \tcode{true} + public: + subrange() = default; + + constexpr subrange(I i, S s) requires (!StoreSize); + + constexpr subrange(I i, S s, iter_difference_t n) + requires (K == subrange_kind::sized); + + template<@\placeholdernc{not-same-as}@ R> + requires @\placeholdernc{forwarding-range}@ && + ConvertibleTo, I> && ConvertibleTo, S> + constexpr subrange(R&& r) requires (!StoreSize || SizedRange); + + template<@\placeholdernc{forwarding-range}@ R> + requires ConvertibleTo, I> && ConvertibleTo, S> + constexpr subrange(R&& r, iter_difference_t n) + requires (K == subrange_kind::sized) + : subrange{ranges::begin(r), ranges::end(r), n} + {} + + template<@\placeholdernc{not-same-as}@ PairLike> + requires @\placeholdernc{pair-like-convertible-to}@ + constexpr subrange(PairLike&& r) requires (!StoreSize) + : subrange{std::get<0>(std::forward(r)), + std::get<1>(std::forward(r))} + {} + + template<@\placeholdernc{pair-like-convertible-to}@ PairLike> + constexpr subrange(PairLike&& r, iter_difference_t n) + requires (K == subrange_kind::sized) + : subrange{std::get<0>(std::forward(r)), + std::get<1>(std::forward(r)), n} + {} + + template<@\placeholdernc{not-same-as}@ PairLike> + requires @\placeholdernc{pair-like-convertible-from}@ + constexpr operator PairLike() const; + + constexpr I begin() const; + constexpr S end() const; + + constexpr bool empty() const; + constexpr iter_difference_t size() const + requires (K == subrange_kind::sized); + + [[nodiscard]] constexpr subrange next(iter_difference_t n = 1) const; + [[nodiscard]] constexpr subrange prev(iter_difference_t n = 1) const + requires BidirectionalIterator; + constexpr subrange& advance(iter_difference_t n); + + friend constexpr I begin(subrange&& r) { return r.begin(); } + friend constexpr S end(subrange&& r) { return r.end(); } + }; + + template S> + subrange(I, S, iter_difference_t) -> subrange; + + template<@\placeholder{iterator-sentinel-pair}@ P> + subrange(P) -> subrange, tuple_element_t<1, P>>; + + template<@\placeholder{iterator-sentinel-pair}@ P> + subrange(P, iter_difference_t>) -> + subrange, tuple_element_t<1, P>, subrange_kind::sized>; + + template<@\placeholder{forwarding-range}@ R> + subrange(R&&) -> + subrange, sentinel_t, + (SizedRange || SizedSentinel, iterator_t>) + ? subrange_kind::sized : subrange_kind::unsized>; + + template<@\placeholder{forwarding-range}@ R> + subrange(R&&, iter_difference_t>) -> + subrange, sentinel_t, subrange_kind::sized>; + + template + requires (N < 2) + constexpr auto get(const subrange& r); +} + +namespace std { + using ranges::get; +} +\end{codeblock} + +\rSec3[range.subrange.ctor]{Constructors and conversions} + +\indexlibrary{\idxcode{subrange}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr subrange(I i, S s) requires (!StoreSize); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{begin_} with \tcode{i} and \tcode{end_} with +\tcode{s}. +\end{itemdescr} + +\indexlibrary{\idxcode{subrange}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr subrange(I i, S s, iter_difference_t n) + requires (K == subrange_kind::sized); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects \tcode{n == ranges::distance(i, s)}. + +\pnum +\effects Initializes \tcode{begin_} with \tcode{i} and \tcode{end_} with +\tcode{s}. If \tcode{StoreSize} is \tcode{true}, initializes \tcode{size_} with +\tcode{n}. + +\pnum +\begin{note} +Accepting the length of the range and storing it to later return from +\tcode{size()} enables \tcode{subrange} to model \libconcept{SizedRange} even +when it stores an iterator and sentinel that do not model +\libconcept{SizedSentinel}. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{subrange}!\idxcode{subrange}}% +\begin{itemdecl} +template<@\placeholdernc{not-same-as}@ R> + requires @\placeholdernc{forwarding-range}@ && + ConvertibleTo, I> && ConvertibleTo, S> +constexpr subrange(R&& r) requires (!StoreSize || SizedRange); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{itemize} +\item If \tcode{StoreSize} is \tcode{true}, +\tcode{subrange\{ranges::begin(r), ranges::end(r), ranges::size(r)\}}. +\item Otherwise, \tcode{subrange\{ranges::begin(r), ranges::end(r)\}}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{operator \placeholder{PairLike}}!\idxcode{subrange}}% +\begin{itemdecl} +template<@\placeholdernc{not-same-as}@ PairLike> + requires @\placeholdernc{pair-like-convertible-from}@ +constexpr operator PairLike() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return PairLike(begin_, end_);} +\end{itemdescr} + +\rSec3[range.subrange.access]{Accessors} + +\indexlibrary{\idxcode{begin}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr I begin() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return begin_;} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr S end() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{empty}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr bool empty() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return begin_ == end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{size}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr iter_difference_t size() const + requires (K == subrange_kind::sized); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\begin{itemize} +\item If \tcode{StoreSize} is \tcode{true}, equivalent to: \tcode{return size_;} +\item Otherwise, equivalent to: \tcode{return end_ - begin_;} +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{next}!\idxcode{subrange}}% +\begin{itemdecl} +[[nodiscard]] constexpr subrange next(iter_difference_t n = 1) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +tmp.advance(n); +return tmp; +\end{codeblock} + +\pnum +\begin{note} +If \tcode{I} does not model \libconcept{ForwardIterator}, \tcode{next} +can invalidate \tcode{*this}. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{prev}!\idxcode{subrange}}% +\begin{itemdecl} +[[nodiscard]] constexpr subrange prev(iter_difference_t n = 1) const + requires BidirectionalIterator; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +tmp.advance(-n); +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{advance}!\idxcode{subrange}}% +\begin{itemdecl} +constexpr subrange& advance(iter_difference_t n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{itemize} +\item If \tcode{StoreSize} is \tcode{true}, +\begin{codeblock} +size_ -= n - ranges::advance(begin_, n, end_); +return *this; +\end{codeblock} +\item Otherwise, +\begin{codeblock} +ranges::advance(begin_, n, end_); +return *this; +\end{codeblock} +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{get}!\idxcode{subrange}}% +\begin{itemdecl} +template + requires (N < 2) +constexpr auto get(const subrange& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +if constexpr (N == 0) + return r.begin(); +else + return r.end(); +\end{codeblock} +\end{itemdescr} + + +\rSec1[range.adaptors]{Range adaptors} + +\pnum +This subclause defines \term{range adaptors}, which are utilities that transform a +\libconcept{Range} into a \libconcept{View} with custom behaviors. These +adaptors can be chained to create pipelines of range transformations that +evaluate lazily as the resulting view is iterated. + +\pnum +Range adaptors are declared in namespace \tcode{std::ranges::view}. + +\pnum +The bitwise \logop{OR} operator is overloaded for the purpose of creating adaptor chain +pipelines. The adaptors also support function call syntax with equivalent +semantics. + +\pnum +\begin{example} +\begin{codeblock} +vector ints{0,1,2,3,4,5}; +auto even = [](int i){ return 0 == i % 2; }; +auto square = [](int i) { return i * i; }; +for (int i : ints | view::filter(even) | view::transform(square)) { + cout << i << ' '; // prints: 0 4 16 +} +assert(ranges::equal(ints | view::filter(even), view::filter(ints, even))); +\end{codeblock} +\end{example} + +\rSec2[range.adaptor.object]{Range adaptor objects} + +\pnum +A \term{range adaptor closure object} is a unary function object that accepts +a \libconcept{ViewableRange} argument and returns a \libconcept{View}. For +a range adaptor closure object \tcode{C} and an expression \tcode{R} such that +\tcode{decltype((R))} models \libconcept{ViewableRange}, the following +expressions are equivalent and yield a \libconcept{View}: + +\begin{codeblock} +C(R) +R | C +\end{codeblock} + +Given an additional range adaptor closure object \tcode{D}, +the expression \tcode{C | D} is well-formed and produces another range adaptor +closure object such that the following two expressions are equivalent: + +\begin{codeblock} +R | C | D +R | (C | D) +\end{codeblock} + +\pnum +A \term{range adaptor object} is a +customization point object\iref{customization.point.object} +that accepts a \libconcept{ViewableRange} as its first argument and returns a +\libconcept{View}. + +\pnum +If a range adaptor object accepts only one argument, +then it is a range adaptor closure object. + +\pnum +If a range adaptor object accepts more than one argument, +then the following expressions are equivalent: + +\begin{codeblock} +@\placeholdernc{adaptor}@(range, args...) +@\placeholdernc{adaptor}@(args...)(range) +range | @\placeholdernc{adaptor}@(args...) +\end{codeblock} + +In this case, \tcode{\placeholdernc{adaptor}(args...)} is a range adaptor +closure object. + +\rSec2[range.semi.wrap]{Semiregular wrapper} + +\pnum +Many of the types in this subclause are specified in terms of +an exposition-only class template \tcode{\placeholder{semiregular}}. +\tcode{\placeholder{semiregular}} behaves exactly like \tcode{optional} +with the following differences: + +\begin{itemize} +\item \tcode{\placeholder{semiregular}} constrains +its type parameter \tcode{T} with +\tcode{\libconcept{CopyConstructible} \&\& is_object_v}. + +\item If \tcode{T} models \libconcept{DefaultConstructible}, the default +constructor of \tcode{\placeholder{semiregular}} is equivalent to: +\begin{codeblock} +constexpr @\placeholder{semiregular}@() noexcept(is_nothrow_default_constructible_v) + : @\placeholder{semiregular}@{in_place} +{ } +\end{codeblock} + +\item If \tcode{\libconcept{Assignable}} is not +satisfied, the copy assignment operator is equivalent to: +\begin{codeblock} +@\placeholder{semiregular}@& operator=(const @\placeholder{semiregular}@& that) + noexcept(is_nothrow_copy_constructible_v) +{ + if (that) emplace(*that); + else reset(); + return *this; +} +\end{codeblock} + +\item If \tcode{\libconcept{Assignable}} is not satisfied, +the move assignment operator is equivalent to: +\begin{codeblock} +@\placeholder{semiregular}@& operator=(@\placeholder{semiregular}@&& that) + noexcept(is_nothrow_move_constructible_v) +{ + if (that) emplace(std::move(*that)); + else reset(); + return *this; +} +\end{codeblock} +\end{itemize} + +\rSec2[range.all]{All view} + +\pnum +\tcode{view::all} returns a \libconcept{View} that includes all elements of +its \libconcept{Range} argument. + +\pnum +The name \tcode{view::all} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpression \tcode{E}, the expression +\tcode{view::all(E)} is expression-equivalent to: + +\begin{itemize} +\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{subrange\{E\}}. +\end{itemize} + +\rSec3[range.view.ref]{\placeholder{ref-view}} + +\begin{codeblock} +namespace std::ranges { + template + requires is_object_v + class @\placeholder{ref-view}@ : public view_interface<@\placeholder{ref-view}@> { + private: + R* r_ = nullptr; // \expos + public: + constexpr @\placeholdernc{ref-view}@() noexcept = default; + + template<@\placeholder{not-same-as}@<@\placeholder{ref-view}@> T> + requires @\seebelow@ + constexpr @\placeholder{ref-view}@(T&& t); + + constexpr R& base() const { return *r_; } + + constexpr iterator_t begin() const { return ranges::begin(*r_); } + constexpr sentinel_t end() const { return ranges::end(*r_); } + + constexpr bool empty() const + requires requires { ranges::empty(*r_); } + { return ranges::empty(*r_); } + + constexpr auto size() const requires SizedRange + { return ranges::size(*r_); } + + constexpr auto data() const requires ContiguousRange + { return ranges::data(*r_); } + + friend constexpr iterator_t begin(@\placeholder{ref-view}@ r) + { return r.begin(); } + + friend constexpr sentinel_t end(@\placeholder{ref-view}@ r) + { return r.end(); } + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{\placeholder{ref-view}}!\idxcode{\placeholder{ref-view}}}% +\begin{itemdecl} +template<@\placeholder{not-same-as}@<@\placeholder{ref-view}@> T> + requires @\seebelow@ +constexpr @\placeholder{ref-view}@(T&& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks Let \tcode{\placeholder{FUN}} denote the exposition-only functions +\begin{codeblock} +void @\placeholder{FUN}@(R&); +void @\placeholder{FUN}@(R&&) = delete; +\end{codeblock} +The expression in the \grammarterm{requires-clause} is equivalent to +\begin{codeblock} +ConvertibleTo && requires { @\placeholder{FUN}@(declval()); } +\end{codeblock} + +\pnum +\effects +Initializes \tcode{r_} with +\tcode{addressof(static_cast(std::forward(t)))}. +\end{itemdescr} + + +\rSec2[range.filter]{Filter view} + +\rSec3[range.filter.overview]{Overview} + +\pnum +\tcode{filter_view} presents a \libconcept{View} of an underlying sequence +without the elements that fail to satisfy a predicate. + +\pnum +\begin{example} +\begin{codeblock} +vector is{ 0, 1, 2, 3, 4, 5, 6 }; +filter_view evens{is, [](int i) { return 0 == i % 2; }}; +for (int i : evens) + cout << i << ' '; // prints: 0 2 4 6 +\end{codeblock} +\end{example} + +\rSec3[range.filter.view]{Class template \tcode{filter_view}} + +\begin{codeblock} +namespace std::ranges { + template> Pred> + requires View && is_object_v + class filter_view : public view_interface> { + private: + V base_ = V(); // \expos + @\placeholdernc{semiregular}@ pred_; // \expos + + class iterator; // \expos + class sentinel; // \expos + + public: + filter_view() = default; + constexpr filter_view(V base, Pred pred); + template + requires ViewableRange && Constructible> + constexpr filter_view(R&& r, Pred pred); + + constexpr V base() const; + + constexpr iterator begin(); + constexpr auto end() { + if constexpr (CommonRange) + return iterator{*this, ranges::end(base_)}; + else + return sentinel{*this}; + } + }; + + template + filter_view(R&&, Pred) -> filter_view, Pred>; +} +\end{codeblock} + +\indexlibrary{\idxcode{filter_view}!\idxcode{filter_view}}% +\begin{itemdecl} +constexpr filter_view(V base, Pred pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)} and initializes +\tcode{pred_} with \tcode{std::move(pred)}. +\end{itemdescr} + +\indexlibrary{\idxcode{filter_view}!\idxcode{filter_view}}% +\begin{itemdecl} +template + requires ViewableRange && Constructible> +constexpr filter_view(R&& r, Pred pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))} +and initializes \tcode{pred_} with \tcode{std::\brk{}move(pred)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{filter_view}}% +\begin{itemdecl} +constexpr V base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return base_;} +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{filter_view}}% +\begin{itemdecl} +constexpr iterator begin(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{pred_.has_value()}. + +\pnum +\returns +\tcode{\{*this, ranges::find_if(base_, ref(*pred_))\}}. + +\pnum +\remarks In order to provide the amortized constant time complexity required by +the \libconcept{Range} concept, this function caches the result within the +\tcode{filter_view} for use on subsequent calls. +\end{itemdescr} + +\rSec3[range.filter.iterator]{Class \tcode{filter_view::iterator}} + +\indexlibrary{\idxcode{iterator}!\idxcode{filter_view}}% +\begin{codeblock} +namespace std::ranges { + template + class filter_view::iterator { + private: + iterator_t current_ = iterator_t(); // \expos + filter_view* parent_ = nullptr; // \expos + public: + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; + using value_type = iter_value_t>; + using difference_type = iter_difference_t>; + + iterator() = default; + constexpr iterator(filter_view& parent, iterator_t current); + + constexpr iterator_t base() const; + constexpr iter_reference_t> operator*() const; + constexpr iterator_t operator->() const + requires @\placeholder{has-arrow}@>; + + constexpr iterator& operator++(); + constexpr void operator++(int); + constexpr iterator operator++(int) requires ForwardRange; + + constexpr iterator& operator--() requires BidirectionalRange; + constexpr iterator operator--(int) requires BidirectionalRange; + + friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable>; + friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable>; + + friend constexpr iter_rvalue_reference_t> iter_move(const iterator& i) + noexcept(noexcept(ranges::iter_move(i.current_))); + friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) + requires IndirectlySwappable>; + }; +} +\end{codeblock} + +\pnum +Modification of the element a \tcode{filter_view::iterator} denotes is +permitted, but results in undefined behavior if the resulting value does not +satisfy the filter predicate. + +\pnum +\tcode{iterator::iterator_concept} is defined as follows: +\begin{itemize} +\item If \tcode{V} models \libconcept{BidirectionalRange}, then +\tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. + +\item Otherwise, if \tcode{V} models \libconcept{ForwardRange}, then +\tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. + +\item Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +\tcode{iterator::iterator_category} is defined as follows: +\begin{itemize} +\item Let \tcode{C} denote the type +\tcode{iterator_traits>::iterator_category}. + +\item If \tcode{C} models \tcode{DerivedFrom}, +then \tcode{iterator_category} denotes \tcode{bi\-directional_iterator_tag}. + +\item Otherwise, if \tcode{C} models \tcode{DerivedFrom}, +then \tcode{iterator_category} denotes \tcode{forward_iterator_tag}. + +\item Otherwise, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\indexlibrary{\idxcode{iterator}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator(filter_view& parent, iterator_t current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{current_} with \tcode{current} and +\tcode{parent_} with \tcode{addressof(parent)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator*}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iter_reference_t> operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return *current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator->}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator_t operator->() const + requires @\placeholder{has-arrow}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +current_ = ranges::find_if(++current_, ranges::end(parent_->base_), ref(*parent_->pred_)); +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{++*this}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator operator++(int) requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator& operator--() requires BidirectionalRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +do + --current_; +while (!invoke(*parent_->pred_, *current_)); +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +constexpr iterator operator--(int) requires BidirectionalRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ == y.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{iter_move}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +friend constexpr iter_rvalue_reference_t> iter_move(const iterator& i) + noexcept(noexcept(ranges::iter_move(i.current_))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return ranges::iter_move(i.current_);} +\end{itemdescr} + +\indexlibrary{\idxcode{iter_swap}!\idxcode{filter_view::iterator}}% +\begin{itemdecl} +friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) + requires IndirectlySwappable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{ranges::iter_swap(x.current_, y.current_)}. +\end{itemdescr} + +\rSec3[range.filter.sentinel]{Class \tcode{filter_view::sentinel}} + +\indexlibrary{\idxcode{sentinel}!\idxcode{filter_view}}% +\begin{codeblock} +namespace std::ranges { + template + class filter_view::sentinel { + private: + sentinel_t end_ = sentinel_t(); // \expos + public: + sentinel() = default; + constexpr explicit sentinel(filter_view& parent); + + constexpr sentinel_t base() const; + + friend constexpr bool operator==(const iterator& x, const sentinel& y); + friend constexpr bool operator==(const sentinel& x, const iterator& y); + friend constexpr bool operator!=(const iterator& x, const sentinel& y); + friend constexpr bool operator!=(const sentinel& x, const iterator& y); + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{sentinel}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +constexpr explicit sentinel(filter_view& parent); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{ranges::end(parent)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +constexpr sentinel_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ == y.end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator==(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y == x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{filter_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator!=(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y == x);} +\end{itemdescr} + +\rSec3[range.filter.adaptor]{\tcode{view::filter}} + +\pnum +The name \tcode{view::filter} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpressions \tcode{E} and \tcode{P}, +the expression \tcode{view::filter(E, P)} is expression-equivalent to +\tcode{filter_view\{E, P\}}. + + +\rSec2[range.transform]{Transform view} + +\rSec3[range.transform.overview]{Overview} + +\pnum +\tcode{transform_view} presents +a \libconcept{View} of an underlying sequence after +applying a transformation function to each element. + +\pnum +\begin{example} +\begin{codeblock} +vector is{ 0, 1, 2, 3, 4 }; +transform_view squares{is, [](int i) { return i * i; }}; +for (int i : squares) + cout << i << ' '; // prints: 0 1 4 9 16 +\end{codeblock} +\end{example} + +\rSec3[range.transform.view]{Class template \tcode{transform_view}} + +\begin{codeblock} +namespace std::ranges { + template + requires View && is_object_v && + RegularInvocable>> + class transform_view : public view_interface> { + private: + template struct iterator; // \expos + template struct sentinel; // \expos + + V base_ = V(); // \expos + @\placeholdernc{semiregular}@ fun_; // \expos + + public: + transform_view() = default; + constexpr transform_view(V base, F fun); + template + requires ViewableRange && Constructible> + constexpr transform_view(R&& r, F fun); + + constexpr V base() const; + + constexpr iterator begin(); + constexpr iterator begin() const + requires Range && + RegularInvocable>>; + + constexpr sentinel end(); + constexpr iterator end() requires CommonRange; + constexpr sentinel end() const + requires Range && + RegularInvocable>>; + constexpr iterator end() const + requires CommonRange && + RegularInvocable>>; + + constexpr auto size() requires SizedRange { return ranges::size(base_); } + constexpr auto size() const requires SizedRange + { return ranges::size(base_); } + }; + + template + transform_view(R&&, F) -> transform_view, F>; +} +\end{codeblock} + +\indexlibrary{\idxcode{transform_view}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr transform_view(V base, F fun); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)} and +\tcode{fun_} with \tcode{std::move(fun)}. +\end{itemdescr} + +\indexlibrary{\idxcode{transform_view}!\idxcode{transform_view}}% +\begin{itemdecl} +template + requires ViewableRange && Constructible> +constexpr transform_view(R&& r, F fun); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))} +and \tcode{fun_} with \tcode{std::move(fun)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr V base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return base_;} +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr iterator begin(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return iterator{*this, ranges::begin(base_)}; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr iterator begin() const + requires Range && + RegularInvocable>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return iterator{*this, ranges::begin(base_)}; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr sentinel end(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return sentinel{ranges::end(base_)}; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr iterator end() requires CommonRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return iterator{*this, ranges::end(base_)}; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr sentinel end() const + requires Range && + RegularInvocable>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return sentinel{ranges::end(base_)}; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{transform_view}}% +\begin{itemdecl} +constexpr iterator end() const + requires CommonRange && + RegularInvocable>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return iterator{*this, ranges::end(base_)}; +\end{codeblock} +\end{itemdescr} + +\rSec3[range.transform.iterator]{Class template \tcode{transform_view::iterator}} + +\begin{codeblock} +namespace std::ranges { + template + template + class transform_view::iterator { + private: + using Parent = // \expos + conditional_t; + using Base = // \expos + conditional_t; + iterator_t current_ = // \expos + iterator_t(); + Parent* parent_ = nullptr; // \expos + public: + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; + using value_type = + remove_cvref_t>>>; + using difference_type = iter_difference_t>; + + iterator() = default; + constexpr iterator(Parent& parent, iterator_t current); + constexpr iterator(iterator i) + requires Const && ConvertibleTo, iterator_t>; + + constexpr iterator_t base() const; + constexpr decltype(auto) operator*() const + { return invoke(*parent_->fun_, *current_); } + + constexpr iterator& operator++(); + constexpr void operator++(int); + constexpr iterator operator++(int) requires ForwardRange; + + constexpr iterator& operator--() requires BidirectionalRange; + constexpr iterator operator--(int) requires BidirectionalRange; + + constexpr iterator& operator+=(difference_type n) + requires RandomAccessRange; + constexpr iterator& operator-=(difference_type n) + requires RandomAccessRange; + constexpr decltype(auto) operator[](difference_type n) const + requires RandomAccessRange + { return invoke(*parent_->fun_, current_[n]); } + + friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable>; + friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable>; + + friend constexpr bool operator<(const iterator& x, const iterator& y) + requires RandomAccessRange; + friend constexpr bool operator>(const iterator& x, const iterator& y) + requires RandomAccessRange; + friend constexpr bool operator<=(const iterator& x, const iterator& y) + requires RandomAccessRange; + friend constexpr bool operator>=(const iterator& x, const iterator& y) + requires RandomAccessRange; + + friend constexpr iterator operator+(iterator i, difference_type n) + requires RandomAccessRange; + friend constexpr iterator operator+(difference_type n, iterator i) + requires RandomAccessRange; + + friend constexpr iterator operator-(iterator i, difference_type n) + requires RandomAccessRange; + friend constexpr difference_type operator-(const iterator& x, const iterator& y) + requires RandomAccessRange; + + friend constexpr decltype(auto) iter_move(const iterator& i) + noexcept(noexcept(invoke(*i.parent_->fun_, *i.current_))) + { + if constexpr (is_lvalue_reference_v) + return std::move(*i); + else + return *i; + } + + friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) + requires IndirectlySwappable>; + }; +} +\end{codeblock} + +\pnum +\tcode{iterator::iterator_concept} is defined as follows: +\begin{itemize} +\item If \tcode{V} models \libconcept{RandomAccessRange}, then +\tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. + +\item Otherwise, if \tcode{V} models \libconcept{BidirectionalRange}, then +\tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. + +\item Otherwise, if \tcode{V} models \libconcept{ForwardRange}, then +\tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. + +\item Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +Let \tcode{C} denote the type +\tcode{iterator_traits>::iterator_category}. +If \tcode{C} models \tcode{\libconcept{Derived\-From}}, +then \tcode{iterator_category} denotes +\tcode{random_access_iterator_tag}; otherwise, +\tcode{iterator_category} denotes \tcode{C}. + +\indexlibrary{\idxcode{iterator}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator(Parent& parent, iterator_t current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{current_} with \tcode{current} and +\tcode{parent_} with \tcode{addressof(parent)}. +\end{itemdescr} + +\indexlibrary{\idxcode{iterator}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +constexpr iterator(iterator i) + requires Const && ConvertibleTo, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{current_} with \tcode{std::move(i.current_)} and +\tcode{parent_} with \tcode{i.parent_}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +++current_; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{++current_}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator operator++(int) requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator--() requires BidirectionalRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +--current_; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator operator--(int) requires BidirectionalRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator+=}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator+=(difference_type n) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +current_ += n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-=}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +constexpr iterator& operator-=(difference_type n) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +current_ -= n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ == y.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator<}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator<(const iterator& x, const iterator& y) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ < y.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator>}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator>(const iterator& x, const iterator& y) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y < x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator<=(const iterator& x, const iterator& y) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y < x);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr bool operator>=(const iterator& x, const iterator& y) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x < y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator+}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +friend constexpr iterator operator+(iterator i, difference_type n) + requires RandomAccessRange; +friend constexpr iterator operator+(difference_type n, iterator i) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return iterator\{*i.parent_, i.current_ + n\};} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr iterator operator-(iterator i, difference_type n) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return iterator\{*i.parent_, i.current_ - n\};} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-}!\idxcode{transform_view::iterator}}% +\begin{itemdecl} +friend constexpr difference_type operator-(const iterator& x, const iterator& y) + requires RandomAccessRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ - y.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{iter_swap}!\idxcode{transform_view::iterator}} +\begin{itemdecl} +friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.current_, y.current_))) + requires IndirectlySwappable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{ranges::iter_swap(x.current_, y.current_)}. +\end{itemdescr} + + +\rSec3[range.transform.sentinel]{Class template \tcode{transform_view::sentinel}} + +\begin{codeblock} +namespace std::ranges { + template + template + class transform_view::sentinel { + private: + using Parent = // \expos + conditional_t; + using Base = conditional_t; // \expos + sentinel_t end_ = sentinel_t(); // \expos + public: + sentinel() = default; + constexpr explicit sentinel(sentinel_t end); + constexpr sentinel(sentinel i) + requires Const && ConvertibleTo, sentinel_t>; + + constexpr sentinel_t base() const; + + friend constexpr bool operator==(const iterator& x, const sentinel& y); + friend constexpr bool operator==(const sentinel& x, const iterator& y); + friend constexpr bool operator!=(const iterator& x, const sentinel& y); + friend constexpr bool operator!=(const sentinel& x, const iterator& y); + + friend constexpr iter_difference_t> + operator-(const iterator& x, const sentinel& y) + requires SizedSentinel, iterator_t>; + friend constexpr iter_difference_t> + operator-(const sentinel& y, const iterator& x) + requires SizedSentinel, iterator_t>; + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{sentinel}!\idxcode{transform_view::sentinel}} +\begin{itemdecl} +constexpr explicit sentinel(sentinel_t end); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{end}. +\end{itemdescr} + +\indexlibrary{\idxcode{sentinel}!\idxcode{transform_view::sentinel}} +\begin{itemdecl} +constexpr sentinel(sentinel i) + requires Const && ConvertibleTo, sentinel_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{std::move(i.end_)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{transform_view::sentinel}} +\begin{itemdecl} +constexpr sentinel_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{transform_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ == y.end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{transform_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y == x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{transform_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{transform_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator!=(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y == x);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{transform_view::sentinel}}% +\begin{itemdecl} +friend constexpr iter_difference_t> + operator-(const iterator& x, const sentinel& y) + requires SizedSentinel, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ - y.end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{transform_view::sentinel}}% +\begin{itemdecl} +friend constexpr iter_difference_t> + operator-(const sentinel& y, const iterator& x) + requires SizedSentinel, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.end_ - y.current_;} +\end{itemdescr} + +\rSec3[range.transform.adaptor]{\tcode{view::transform}} + +\pnum +The name \tcode{view::transform} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpressions \tcode{E} and \tcode{F}, the expression +\tcode{view::transform(E, F)} is expression-equivalent to +\tcode{transform_view\{E, F\}}. + + +\rSec2[range.iota]{Iota view} + +\rSec3[range.iota.overview]{Overview} + +\pnum +\tcode{iota_view} generates a +sequence of elements by repeatedly incrementing an initial value. + +\pnum +\begin{example} +\begin{codeblock} +for (int i : iota_view{1, 10}) + cout << i << ' '; // prints: 1 2 3 4 5 6 7 8 9 +\end{codeblock} +\end{example} + +\rSec3[range.iota.view]{Class template \tcode{iota_view}} + +\begin{codeblock} +namespace std::ranges { + template + concept @\placeholdernc{Decrementable}@ = // \expos + @\seebelow@; + template + concept @\placeholdernc{Advanceable}@ = // \expos + @\seebelow@; + + template + requires @\placeholdernc{weakly-equality-comparable-with}@ + class iota_view : public view_interface> { + private: + struct iterator; // \expos + struct sentinel; // \expos + W value_ = W(); // \expos + Bound bound_ = Bound(); // \expos + public: + iota_view() = default; + constexpr explicit iota_view(W value); + constexpr iota_view(type_identity_t value, + type_identity_t bound); + + constexpr iterator begin() const; + constexpr sentinel end() const; + constexpr iterator end() const requires Same; + + constexpr auto size() const + requires (Same && @\placeholdernc{Advanceable}@) || + (Integral && Integral) || + SizedSentinel + { return bound_ - value_; } + }; + + template + requires (!Integral || !Integral || is_signed_v == is_signed_v) + iota_view(W, Bound) -> iota_view; +} +\end{codeblock} + +\pnum +The exposition-only \tcode{\placeholder{Decrementable}} concept is equivalent to: +\begin{itemdecl} +template + concept @\placeholder{Decrementable}@ = + Incrementable && requires(I i) { + { --i } -> Same; + { i-- } -> Same; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +When an object is in the domain of both pre- and post-decrement, +the object is said to be \term{decrementable}. + +\pnum +Let \tcode{a} and \tcode{b} be equal objects of type \tcode{I}. +\tcode{I} models \tcode{\placeholdernc{Decrementable}} only if +\begin{itemize} +\item If \tcode{a} and \tcode{b} are decrementable, + then the following are all true: + \begin{itemize} + \item \tcode{addressof(--a) == addressof(a)} + \item \tcode{bool(a-- == b)} + \item \tcode{bool(((void)a--, a) == --b)} + \item \tcode{bool(++(--a) == b)}. + \end{itemize} +\item If \tcode{a} and \tcode{b} are incrementable, + then \tcode{bool(--(++a) == b)}. +\end{itemize} +\end{itemdescr} + +\pnum +The exposition-only \tcode{\placeholder{Advanceable}} concept is equivalent to: +\begin{itemdecl} +template + concept @\placeholder{Advanceable}@ = + @\placeholdernc{Decrementable}@ && StrictTotallyOrdered && + requires(I i, const I j, const iter_difference_t n) { + { i += n } -> Same; + { i -= n } -> Same; + { j + n } -> Same; + { n + j } -> Same; + { j - n } -> Same; + { j - j } -> Same>; + }; +\end{itemdecl} + +Let \tcode{a} and \tcode{b} be objects of type \tcode{I} such that +\tcode{b} is reachable from \tcode{a} +after \tcode{n} applications of \tcode{++a}, +for some value \tcode{n} of type \tcode{iter_difference_t}, +and let \tcode{D} be \tcode{iter_difference_t}. +\tcode{I} models \tcode{\placeholdernc{Advanceable}} only if +\begin{itemize} +\item \tcode{(a += n)} is equal to \tcode{b}. +\item \tcode{addressof(a += n)} is equal to \tcode{addressof(a)}. +\item \tcode{(a + n)} is equal to \tcode{(a += n)}. +\item For any two positive values + \tcode{x} and \tcode{y} of type \tcode{D}, + if \tcode{(a + D(x + y))} is well-defined, then + \tcode{(a + D(x + y))} is equal to \tcode{((a + x) + y)}. +\item \tcode{(a + D(0))} is equal to \tcode{a}. +\item If \tcode{(a + D(n - 1))} is well-defined, then + \tcode{(a + n)} is equal to \tcode{++(a + D(n - 1))}. +\item \tcode{(b += -n)} is equal to \tcode{a}. +\item \tcode{(b -= n)} is equal to \tcode{a}. +\item \tcode{addressof(b -= n)} is equal to \tcode{addressof(b)}. +\item \tcode{(b - n)} is equal to \tcode{(b -= n)}. +\item \tcode{(b - a)} is equal to \tcode{n}. +\item \tcode{(a - b)} is equal to \tcode{-n}. +\item \tcode{bool(a <= b)} is \tcode{true}. +\end{itemize} + +\indexlibrary{\idxcode{iota_view}!\idxcode{iota_view}}% +\begin{itemdecl} +constexpr explicit iota_view(W value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Bound} denotes \tcode{unreachable_sentinel_t} or +\tcode{Bound()} is reachable from \tcode{value}. + +\pnum +\effects Initializes \tcode{value_} with \tcode{value}. +\end{itemdescr} + +\indexlibrary{\idxcode{iota_view}!\idxcode{iota_view}}% +\begin{itemdecl} +constexpr iota_view(type_identity_t value, type_identity_t bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Bound} denotes \tcode{unreachable_sentinel_t} or +\tcode{bound} is reachable from \tcode{value}. + +\pnum +\effects Initializes \tcode{value_} with \tcode{value} and +\tcode{bound_} with \tcode{bound}. +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{iota_view}}% +\begin{itemdecl} +constexpr iterator begin() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return iterator\{value_\};} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{iota_view}}% +\begin{itemdecl} +constexpr sentinel end() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return sentinel\{bound_\};} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{iota_view}}% +\begin{itemdecl} +constexpr iterator end() const requires Same; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return iterator\{bound_\};} +\end{itemdescr} + +\rSec3[range.iota.iterator]{Class \tcode{iota_view::iterator}} + +\begin{codeblock} +namespace std::ranges { + template + struct iota_view::iterator { + private: + W value_ = W(); // \expos + public: + using iterator_category = @\seebelow@; + using value_type = W; + using difference_type = iter_difference_t; + + iterator() = default; + constexpr explicit iterator(W value); + + constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v); + + constexpr iterator& operator++(); + constexpr void operator++(int); + constexpr iterator operator++(int) requires Incrementable; + + constexpr iterator& operator--() requires @\placeholdernc{Decrementable}@; + constexpr iterator operator--(int) requires @\placeholdernc{Decrementable}@; + + constexpr iterator& operator+=(difference_type n) + requires @\placeholdernc{Advanceable}@; + constexpr iterator& operator-=(difference_type n) + requires @\placeholdernc{Advanceable}@; + constexpr W operator[](difference_type n) const + requires @\placeholdernc{Advanceable}@; + + friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable; + friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable; + + friend constexpr bool operator<(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; + friend constexpr bool operator>(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; + friend constexpr bool operator<=(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; + friend constexpr bool operator>=(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; + + friend constexpr iterator operator+(iterator i, difference_type n) + requires @\placeholdernc{Advanceable}@; + friend constexpr iterator operator+(difference_type n, iterator i) + requires @\placeholdernc{Advanceable}@; + + friend constexpr iterator operator-(iterator i, difference_type n) + requires @\placeholdernc{Advanceable}@; + friend constexpr difference_type operator-(const iterator& x, const iterator& y) + requires @\placeholdernc{Advanceable}@; + }; +} +\end{codeblock} + +\pnum +\tcode{iterator::iterator_category} is defined as follows: +\begin{itemize} +\item If \tcode{W} models \tcode{\placeholder{Advanceable}}, then +\tcode{iterator_category} is \tcode{random_access_iterator_tag}. +\item Otherwise, if \tcode{W} models \tcode{\placeholder{Decrementable}}, then +\tcode{iterator_category} is \tcode{bidirectional_iterator_tag}. +\item Otherwise, if \tcode{W} models \libconcept{Incrementable}, then +\tcode{iterator_category} is \tcode{forward_iterator_tag}. +\item Otherwise, \tcode{iterator_category} is \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +\begin{note} +Overloads for \tcode{iter_move} and \tcode{iter_swap} are omitted intentionally. +\end{note} + +\indexlibrary{\idxcode{iterator}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr explicit iterator(W value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{value_} with \tcode{value}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator*}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return value_;} + +\pnum +\begin{note} +The \tcode{noexcept} clause is needed by the default \tcode{iter_move} +implementation. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +++value_; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{++*this}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator operator++(int) requires Incrementable; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator--() requires @\placeholdernc{Decrementable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +--value_; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator operator--(int) requires @\placeholdernc{Decrementable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator+=}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator+=(difference_type n) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +value_ += n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-=}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator-=(difference_type n) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +value_ -= n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator[]}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +constexpr W operator[](difference_type n) const + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return value_ + n;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const iterator& y) + requires EqualityComparable; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.value_ == y.value_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires EqualityComparable; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator<}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator<(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.value_ < y.value_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator>}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator>(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y < x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator<=(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y < x);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator>=(const iterator& x, const iterator& y) + requires StrictTotallyOrdered; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x < y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator+}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr iterator operator+(iterator i, difference_type n) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return iterator\{i.value_ + n\};} +\end{itemdescr} + +\indexlibrary{\idxcode{operator+}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr iterator operator+(difference_type n, iterator i) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return i + n;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr iterator operator-(iterator i, difference_type n) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return i + -n;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator-}!\idxcode{iota_view::iterator}} +\begin{itemdecl} +friend constexpr difference_type operator-(const iterator& x, const iterator& y) + requires @\placeholdernc{Advanceable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.value_ - y.value_;} +\end{itemdescr} + +\rSec3[range.iota.sentinel]{Class \tcode{iota_view::sentinel}} + +\begin{codeblock} +namespace std::ranges { + template + struct iota_view::sentinel { + private: + Bound bound_ = Bound(); // \expos + public: + sentinel() = default; + constexpr explicit sentinel(Bound bound); + + friend constexpr bool operator==(const iterator& x, const sentinel& y); + friend constexpr bool operator==(const sentinel& x, const iterator& y); + friend constexpr bool operator!=(const iterator& x, const sentinel& y); + friend constexpr bool operator!=(const sentinel& x, const iterator& y); + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{sentinel}!\idxcode{iota_view::sentinel}} +\begin{itemdecl} +constexpr explicit sentinel(Bound bound); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{bound_} with \tcode{bound}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{iota_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.value_ == y.bound_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{iota_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y == x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{iota_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{iota_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator!=(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y == x);} +\end{itemdescr} + +\rSec3[range.iota.adaptor]{\tcode{view::iota}} + +\pnum +The name \tcode{view::iota} denotes a +customization point object\iref{customization.point.object}. +For some subexpressions \tcode{E} and \tcode{F}, the expressions +\tcode{view::iota(E)} and \tcode{view::iota(E, F)} +are expression-equivalent to +\tcode{iota_view\{E\}} and \tcode{iota_view\{E, F\}}, respectively. + + +\rSec2[range.take]{Take view} + +\rSec3[range.take.overview]{Overview} + +\pnum +\tcode{take_view} produces a \libconcept{View} of the first $N$ elements +from another \libconcept{View}, or all the elements if the adapted +\libconcept{View} contains fewer than $N$. + +\pnum +\begin{example} +\begin{codeblock} +vector is{0,1,2,3,4,5,6,7,8,9}; +take_view few{is, 5}; +for (int i : few) + cout << i << ' '; // prints: 0 1 2 3 4 +\end{codeblock} +\end{example} + +\rSec3[range.take.view]{Class template \tcode{take_view}} + +\begin{codeblock} +namespace std::ranges { + template + class take_view : public view_interface> { + private: + V base_ = V(); // \expos + iter_difference_t> count_ = 0; // \expos + template struct sentinel; // \expos + public: + take_view() = default; + constexpr take_view(V base, iter_difference_t> count); + template + requires Constructible> + constexpr take_view(R&& r, iter_difference_t> count); + + constexpr V base() const; + + constexpr auto begin() requires (!@\placeholder{simple-view}@) { + if constexpr (SizedRange) { + if constexpr (RandomAccessRange) + return ranges::begin(base_); + else + return counted_iterator{ranges::begin(base_), size()}; + } else + return counted_iterator{ranges::begin(base_), count_}; + } + + constexpr auto begin() const requires Range { + if constexpr (SizedRange) { + if constexpr (RandomAccessRange) + return ranges::begin(base_); + else + return counted_iterator{ranges::begin(base_), size()}; + } else + return counted_iterator{ranges::begin(base_), count_}; + } + + constexpr auto end() requires (!@\placeholder{simple-view}@) { + if constexpr (SizedRange) { + if constexpr (RandomAccessRange) + return ranges::begin(base_) + size(); + else + return default_sentinel; + } else + return sentinel{ranges::end(base_)}; + } + + constexpr auto end() const requires Range { + if constexpr (SizedRange) { + if constexpr (RandomAccessRange) + return ranges::begin(base_) + size(); + else + return default_sentinel; + } else + return sentinel{ranges::end(base_)}; + } + + constexpr auto size() requires SizedRange { + auto n = ranges::size(base_); + return ranges::min(n, static_cast(count_)); + } + + constexpr auto size() const requires SizedRange { + auto n = ranges::size(base_); + return ranges::min(n, static_cast(count_)); + } + }; + + template + take_view(R&&, iter_difference_t>) + -> take_view>; +} +\end{codeblock} + +\indexlibrary{\idxcode{take_view}!\idxcode{take_view}}% +\begin{itemdecl} +constexpr take_view(V base, iter_difference_t> count); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)} and +\tcode{count_} with \tcode{count}. +\end{itemdescr} + +\indexlibrary{\idxcode{take_view}!\idxcode{take_view}}% +\begin{itemdecl} +template + requires Constructible> +constexpr take_view(R&& r, iter_difference_t> count); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))} +and \tcode{count_} with \tcode{count}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{take_view}}% +\begin{itemdecl} +constexpr V base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return base_;} +\end{itemdescr} + +\rSec3[range.take.sentinel]{Class template \tcode{take_view::sentinel}} + +\begin{codeblock} +namespace std::ranges { + template + template + class take_view::sentinel { + private: + using Base = conditional_t; // \expos + using CI = counted_iterator>; // \expos + sentinel_t end_ = sentinel_t(); // \expos + public: + sentinel() = default; + constexpr explicit sentinel(sentinel_t end); + constexpr sentinel(sentinel s) + requires Const && ConvertibleTo, sentinel_t>; + + constexpr sentinel_t base() const; + + friend constexpr bool operator==(const sentinel& x, const CI& y); + friend constexpr bool operator==(const CI& y, const sentinel& x); + friend constexpr bool operator!=(const sentinel& x, const CI& y); + friend constexpr bool operator!=(const CI& y, const sentinel& x); + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{sentinel}!\idxcode{take_view::sentinel}} +\begin{itemdecl} +constexpr explicit sentinel(sentinel_t end); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{end}. +\end{itemdescr} + +\indexlibrary{\idxcode{sentinel}!\idxcode{take_view::sentinel}}% +\begin{itemdecl} +constexpr sentinel(sentinel s) + requires Const && ConvertibleTo, sentinel_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{std::move(s.end_)}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{take_view::sentinel}} +\begin{itemdecl} +constexpr sentinel_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{take_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const sentinel& x, const CI& y); +friend constexpr bool operator==(const CI& y, const sentinel& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return y.count() == 0 || y.base() == x.end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{take_view::sentinel}}% +\begin{itemdecl} +friend constexpr bool operator!=(const sentinel& x, const CI& y); +friend constexpr bool operator!=(const CI& y, const sentinel& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\rSec3[range.take.adaptor]{\tcode{view::take}} + +\pnum +The name \tcode{view::take} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpressions \tcode{E} and \tcode{F}, the expression +\tcode{view::take(E, F)} is expression-equivalent to +\tcode{take_view\{E, F\}}. + + +\rSec2[range.join]{Join view} + +\rSec3[range.join.overview]{Overview} + +\pnum +\tcode{join_view} flattens a \libconcept{View} of ranges into a +\libconcept{View}. + +\pnum +\begin{example} +\begin{codeblock} +vector ss{"hello", " ", "world", "!"}; +join_view greeting{ss}; +for (char ch : greeting) + cout << ch; // prints: hello world! +\end{codeblock} +\end{example} + +\rSec3[range.join.view]{Class template \tcode{join_view}} + +\begin{codeblock} +namespace std::ranges { + template + requires View && InputRange>> && + (is_reference_v>> || + View>>) + class join_view : public view_interface> { + private: + using InnerRng = // \expos + iter_reference_t>; + template + struct iterator; // \expos + template + struct sentinel; // \expos + + V base_ = V(); // \expos + all_view inner_ = // \expos, present only when \tcode{!is_reference_v} + all_view(); + public: + join_view() = default; + constexpr explicit join_view(V base); + + template + requires ViewableRange && Constructible> + constexpr explicit join_view(R&& r); + + constexpr auto begin() { + return iterator<@\placeholder{simple-view}@>{*this, ranges::begin(base_)}; + } + + constexpr auto begin() const + requires InputRange && + is_reference_v>> { + return iterator{*this, ranges::begin(base_)}; + } + + constexpr auto end() { + if constexpr (ForwardRange && + is_reference_v && ForwardRange && + CommonRange && CommonRange) + return iterator<@\placeholder{simple-view}@>{*this, ranges::end(base_)}; + else + return sentinel<@\placeholder{simple-view}@>{*this}; + } + + constexpr auto end() const + requires InputRange && + is_reference_v>> { + if constexpr (ForwardRange && + is_reference_v>> && + ForwardRange>> && + CommonRange && + CommonRange>>) + return iterator{*this, ranges::end(base_)}; + else + return sentinel{*this}; + } + }; + + template + explicit join_view(R&&) -> join_view>; +} +\end{codeblock} + +\indexlibrary{\idxcode{join_view}!\idxcode{join_view}}% +\begin{itemdecl} +constexpr explicit join_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)}. +\end{itemdescr} + +\indexlibrary{\idxcode{join_view}!\idxcode{join_view}}% +\begin{itemdecl} +template + requires ViewableRange && Constructible> +constexpr explicit join_view(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))}. +\end{itemdescr} + +\rSec3[range.join.iterator]{Class template \tcode{join_view::iterator}} + +\pnum +\begin{codeblock} +namespace std::ranges { +template + template + struct join_view::iterator { + private: + using Parent = // \expos + conditional_t; + using Base = conditional_t; // \expos + + static constexpr bool ref_is_glvalue = // \expos + is_reference_v>>; + + iterator_t outer_ = iterator_t(); // \expos + iterator_t>> inner_ = // \expos + iterator_t>>(); + Parent* parent_ = nullptr; // \expos + + constexpr void satisfy(); // \expos + public: + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; + using value_type = + iter_value_t>>>; + using difference_type = @\seebelow@; + + iterator() = default; + constexpr iterator(Parent& parent, iterator_t outer); + constexpr iterator(iterator i) + requires Const && + ConvertibleTo, iterator_t> && + ConvertibleTo, + iterator_t>>>; + + constexpr decltype(auto) operator*() const { return *inner_; } + + constexpr iterator_t operator->() const + requires @\placeholder{has-arrow}@>; + + constexpr iterator& operator++(); + constexpr void operator++(int); + constexpr iterator operator++(int) + requires ref_is_glvalue && ForwardRange && + ForwardRange>>; + + constexpr iterator& operator--() + requires ref_is_glvalue && BidirectionalRange && + BidirectionalRange>>; + + constexpr iterator operator--(int) + requires ref_is_glvalue && BidirectionalRange && + BidirectionalRange>>; + + friend constexpr bool operator==(const iterator& x, const iterator& y) + requires ref_is_glvalue && EqualityComparable> && + EqualityComparable>>>; + + friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires ref_is_glvalue && EqualityComparable> && + EqualityComparable>>>; + + friend constexpr decltype(auto) iter_move(const iterator& i) + noexcept(noexcept(ranges::iter_move(i.inner_))) { + return ranges::iter_move(i.inner_); + } + + friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_))); + }; +} +\end{codeblock} + +\pnum +\tcode{iterator::iterator_concept} is defined as follows: +\begin{itemize} +\item If \tcode{ref_is_glvalue} is \tcode{true}, + \begin{itemize} + \item If \tcode{Base} and \tcode{iter_reference_t>} each model + \libconcept{BidirectionalRange}, then \tcode{iterator_concept} denotes + \tcode{bidirectional_iterator_tag}. + \item Otherwise, if \tcode{Base} and \tcode{iter_reference_t>} + each model \libconcept{ForwardRange}, then \tcode{iterator_concept} denotes + \tcode{forward_iterator_tag}. + \end{itemize} +\item Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +\tcode{iterator::iterator_category} is defined as follows: +\begin{itemize} +\item Let \placeholder{OUTERC} denote + \tcode{iterator_traits>::iterator_category}, and + let \placeholder{INNERC} denote + \tcode{iterator_traits>>>::iterator_cate\-gory}. +\item If \tcode{ref_is_glvalue} is \tcode{true}, + \begin{itemize} + \item If \placeholder{OUTERC} and \placeholder{INNERC} each model + \tcode{DerivedFrom}, \tcode{itera\-tor_category} + denotes \tcode{bidirectional_iterator_tag}. + \item Otherwise, if \placeholder{OUTERC} and \placeholder{INNERC} each model + \tcode{DerivedFrom}, \tcode{itera\-tor_category} + denotes \tcode{forward_iterator_tag}. + \end{itemize} +\item Otherwise, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +\tcode{iterator::difference_type} denotes the type: +\begin{codeblock} +common_type_t< + iter_difference_t>, + iter_difference_t>>>> +\end{codeblock} + +\pnum +\tcode{join_view} iterators use the \tcode{satisfy} function to skip over +empty inner ranges. + +\begin{itemdecl} +constexpr void satisfy(); // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto update_inner = [this](iter_reference_t> x) -> decltype(auto) { + if constexpr (ref_is_glvalue) // \tcode{x} is a reference + return (x); // \tcode{(x)} is an lvalue + else + return (parent_->inner_ = view::all(x)); +}; + +for (; outer_ != ranges::end(parent_->base_); ++outer_) { + auto& inner = update_inner(*outer_); + inner_ = ranges::begin(inner); + if (inner_ != ranges::end(inner)) + return; +} +if constexpr (ref_is_glvalue) + inner_ = iterator_t>>(); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{iterator}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator(Parent& parent, iterator_t outer) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{outer_} with \tcode{outer} and +\tcode{parent_} with \tcode{addressof(parent)}; then calls \tcode{satisfy()}. +\end{itemdescr} + +\indexlibrary{\idxcode{iterator}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator(iterator i) + requires Const && + ConvertibleTo, iterator_t> && + ConvertibleTo, + iterator_t>>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{outer_} with \tcode{std::move(i.outer_)}, +\tcode{inner_} with \tcode{std::move(i.inner_)}, and +\tcode{parent_} with \tcode{i.parent_}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator->}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator_t operator->() const + requires @\placeholder{has-arrow}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{return inner_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{inner-range}} be: +\begin{itemize} +\item If \tcode{ref_is_glvalue} is \tcode{true}, \tcode{*outer_}. +\item Otherwise, \tcode{parent_->inner_}. +\end{itemize} + +\pnum +\effects Equivalent to: +\begin{codeblock} +auto&& inner_rng = @\placeholder{inner-range}@; +if (++inner_ == ranges::end(inner_rng)) { + ++outer_; + satisfy(); +} +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{++*this}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator operator++(int) + requires ref_is_glvalue && ForwardRange && + ForwardRange>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator& operator--() + requires ref_is_glvalue && BidirectionalRange && + BidirectionalRange>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +if (outer_ == ranges::end(parent_->base_)) + inner_ = ranges::end(*--outer_); +while (inner_ == ranges::begin(*outer_)) + inner_ = ranges::end(*--outer_); +--inner_; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator\dcr}!\idxcode{join_view::iterator}} +\begin{itemdecl} +constexpr iterator operator--(int) + requires ref_is_glvalue && BidirectionalRange && + BidirectionalRange>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{join_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const iterator& y) + requires ref_is_glvalue && EqualityComparable> && + EqualityComparable>>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return x.outer_ == y.outer_ \&\& x.inner_ == y.inner_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{join_view::iterator}} +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const iterator& y) + requires ref_is_glvalue && EqualityComparable> && + EqualityComparable>>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{iter_swap}!\idxcode{join_view::iterator}} +\begin{itemdecl} +friend constexpr void iter_swap(const iterator& x, const iterator& y) + noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return ranges::iter_swap(x.inner_, y.inner_);} +\end{itemdescr} + +\rSec3[range.join.sentinel]{Class template \tcode{join_view::sentinel}} + +\begin{codeblock} +namespace std::ranges { + template + template + struct join_view::sentinel { + private: + using Parent = // \expos + conditional_t; + using Base = conditional_t; // \expos + sentinel_t end_ = sentinel_t(); // \expos + public: + sentinel() = default; + + constexpr explicit sentinel(Parent& parent); + constexpr sentinel(sentinel s) + requires Const && ConvertibleTo, sentinel_t>; + + friend constexpr bool operator==(const iterator& x, const sentinel& y); + friend constexpr bool operator==(const sentinel& x, const iterator& y); + friend constexpr bool operator!=(const iterator& x, const sentinel& y); + friend constexpr bool operator!=(const sentinel& x, const iterator& y); + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{sentinel}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +constexpr explicit sentinel(Parent& parent); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{ranges::end(parent.base_)}. +\end{itemdescr} + +\indexlibrary{\idxcode{sentinel}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +constexpr sentinel(sentinel s) + requires Const && ConvertibleTo, sentinel_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{end_} with \tcode{std::move(s.end_)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.outer_ == y.end_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator==(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return y == x;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator!=(const iterator& x, const sentinel& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{join_view::sentinel}} +\begin{itemdecl} +friend constexpr bool operator!=(const sentinel& x, const iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(y == x);} +\end{itemdescr} + +\rSec3[range.join.adaptor]{\tcode{view::join}} + +\pnum +The name \tcode{view::join} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpression \tcode{E}, the expression +\tcode{view::join(E)} is expression-equivalent to +\tcode{join_view\{E\}}. + + +\rSec2[range.empty]{Empty view} + +\rSec3[range.empty.overview]{Overview} + +\pnum +\tcode{empty_view} produces a \libconcept{View} of no elements of +a particular type. + +\pnum +\begin{example} +\begin{codeblock} +empty_view e; +static_assert(ranges::empty(e)); +static_assert(0 == e.size()); +\end{codeblock} +\end{example} + +\rSec3[range.empty.view]{Class template \tcode{empty_view}} + +\begin{codeblock} +namespace std::ranges { + template + requires is_object_v + class empty_view : public view_interface> { + public: + static constexpr T* begin() noexcept { return nullptr; } + static constexpr T* end() noexcept { return nullptr; } + static constexpr T* data() noexcept { return nullptr; } + static constexpr ptrdiff_t size() noexcept { return 0; } + static constexpr bool empty() noexcept { return true; } + + friend constexpr T* begin(empty_view) noexcept { return nullptr; } + friend constexpr T* end(empty_view) noexcept { return nullptr; } + }; +} +\end{codeblock} + + +\rSec2[range.single]{Single view} + +\rSec3[range.single.overview]{Overview} + +\pnum +\tcode{single_view} produces a \libconcept{View} that contains +exactly one element of a specified value. + +\pnum +\begin{example} +\begin{codeblock} +single_view s{4}; +for (int i : s) + cout << i; // prints 4 +\end{codeblock} +\end{example} + +\rSec3[range.single.view]{Class template \tcode{single_view}} + +\begin{codeblock} +namespace std::ranges { + template + requires is_object_v + class single_view : public view_interface> { + private: + @\placeholdernc{semiregular}@ value_; // \expos + public: + single_view() = default; + constexpr explicit single_view(const T& t); + constexpr explicit single_view(T&& t); + template + requires Constructible + constexpr single_view(in_place_t, Args&&... args); + + constexpr T* begin() noexcept; + constexpr const T* begin() const noexcept; + constexpr T* end() noexcept; + constexpr const T* end() const noexcept; + static constexpr ptrdiff_t size() noexcept; + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{single_view}!\idxcode{single_view}}% +\begin{itemdecl} +constexpr explicit single_view(const T& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{value_} with \tcode{t}. +\end{itemdescr} + +\indexlibrary{\idxcode{single_view}!\idxcode{single_view}}% +\begin{itemdecl} +constexpr explicit single_view(T&& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{value_} with \tcode{std::move(t)}. +\end{itemdescr} + +\indexlibrary{\idxcode{single_view}!\idxcode{single_view}}% +\begin{itemdecl} +template +constexpr single_view(in_place_t, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{value_} as if by +\tcode{value_\{in_place, std::forward(args)...\}}. +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{single_view}}% +\begin{itemdecl} +constexpr T* begin() noexcept; +constexpr const T* begin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return data();} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{single_view}}% +\begin{itemdecl} +constexpr T* end() noexcept; +constexpr const T* end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return data() + 1;} +\end{itemdescr} + +\indexlibrary{\idxcode{size}!\idxcode{single_view}}% +\begin{itemdecl} +static constexpr ptrdiff_t size() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return 1;} +\end{itemdescr} + +\indexlibrary{\idxcode{data}!\idxcode{single_view}}% +\begin{itemdecl} +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return value_.operator->();} +\end{itemdescr} + +\rSec3[range.single.adaptor]{\tcode{view::single}} + +\pnum +The name \tcode{view::single} denotes a +customization point object\iref{customization.point.object}. +For some subexpression \tcode{E}, the expression +\tcode{view::single(E)} is expression-equivalent to +\tcode{single_view\{E\}}. + + +\rSec2[range.split]{Split view} + +\rSec3[range.split.overview]{Overview} + +\pnum +\tcode{split_view} takes a \libconcept{View} and a delimiter, and splits +the \libconcept{View} into subranges on the delimiter. The delimiter can be +a single element or a \libconcept{View} of elements. + +\pnum +\begin{example} +\begin{codeblock} +string str{"the quick brown fox"}; +split_view sentence{str, ' '}; +for (auto word : sentence) { + for (char ch : word) + cout << ch; + cout << '*'; +} +// The above prints: the*quick*brown*fox* +\end{codeblock} +\end{example} + +\rSec3[range.split.view]{Class template \tcode{split_view}} + +\begin{codeblock} +namespace std::ranges { + template struct @\placeholdernc{require-constant}@; // \expos + + template + concept @\placeholdernc{tiny-range}@ = // \expos + SizedRange && + requires { typename @\placeholdernc{require-constant}@::size()>; } && + (remove_reference_t::size() <= 1); + + template + requires View && View && + 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} + template struct outer_iterator; // \expos + template struct inner_iterator; // \expos + public: + split_view() = default; + constexpr split_view(V base, Pattern pattern); + + template + requires Constructible> && + Constructible> + constexpr split_view(R&& r, P&& p); + + template + requires Constructible> && + Constructible>>> + constexpr split_view(R&& r, iter_value_t> e); + + constexpr auto begin() { + if constexpr (ForwardRange) + return outer_iterator<@\placeholder{simple-view}@>{*this, ranges::begin(base_)}; + else { + current_ = ranges::begin(base_); + return outer_iterator{*this}; + } + } + + constexpr auto begin() const requires ForwardRange && ForwardRange { + return outer_iterator{*this, ranges::begin(base_)}; + } + + constexpr auto end() requires ForwardRange && CommonRange { + return outer_iterator<@\placeholder{simple-view}@>{*this, ranges::end(base_)}; + } + + constexpr auto end() const { + if constexpr (ForwardRange && ForwardRange && CommonRange) + return outer_iterator{*this, ranges::end(base_)}; + else + return default_sentinel; + } + }; + + template + split_view(R&&, P&&) -> split_view, all_view

>; + + template + split_view(R&&, iter_value_t>) + -> split_view, single_view>>>; +} +\end{codeblock} + +\indexlibrary{\idxcode{split_view}!\idxcode{split_view}}% +\begin{itemdecl} +constexpr split_view(V base, Pattern pattern); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)}, and +\tcode{pattern_} with \tcode{std::move(pattern)}. +\end{itemdescr} + +\indexlibrary{\idxcode{split_view}!\idxcode{split_view}}% +\begin{itemdecl} +template + requires Constructible> && + Constructible> +constexpr split_view(R&& r, P&& p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{base_} with \tcode{view::all(std::forward(r))} and +\tcode{pattern_} with \tcode{view::all(std\brk{}::forward

(p))}. +\end{itemdescr} + +\indexlibrary{\idxcode{split_view}!\idxcode{split_view}}% +\begin{itemdecl} +template + requires Constructible> && + Constructible>>> +constexpr split_view(R&& r, iter_value_t> e); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{base_} with \tcode{view::all(std::forward(r))} and +\tcode{pattern_} with \tcode{single_view\{\brk{}std::move(e)\}}. +\end{itemdescr} + +\rSec3[range.split.outer]{Class template \tcode{split_view::outer_iterator}} + +\begin{codeblock} +namespace std::ranges { + template + template + struct split_view::outer_iterator { + private: + using Parent = // \expos + conditional_t; + using Base = // \expos + conditional_t; + Parent* parent_ = nullptr; // \expos + iterator_t current_ = // \expos, present only if \tcode{V} models \libconcept{ForwardRange} + iterator_t(); + + public: + using iterator_concept = + conditional_t, forward_iterator_tag, input_iterator_tag>; + using iterator_category = input_iterator_tag; + struct value_type; // see \ref{range.split.outer.value} + using difference_type = iter_difference_t>; + + outer_iterator() = default; + constexpr explicit outer_iterator(Parent& parent) + requires (!ForwardRange); + constexpr outer_iterator(Parent& parent, iterator_t current) + requires ForwardRange; + constexpr outer_iterator(outer_iterator i) + requires Const && ConvertibleTo, iterator_t>; + + constexpr value_type operator*() const; + + constexpr outer_iterator& operator++(); + constexpr decltype(auto) operator++(int) { + if constexpr (ForwardRange) { + auto tmp = *this; + ++*this; + return tmp; + } else + ++*this; + } + + friend constexpr bool operator==(const outer_iterator& x, const outer_iterator& y) + requires ForwardRange; + friend constexpr bool operator!=(const outer_iterator& x, const outer_iterator& y) + requires ForwardRange; + + friend constexpr bool operator==(const outer_iterator& x, default_sentinel_t); + friend constexpr bool operator==(default_sentinel_t, const outer_iterator& x); + friend constexpr bool operator!=(const outer_iterator& x, default_sentinel_t y); + friend constexpr bool operator!=(default_sentinel_t y, const outer_iterator& x); + }; +} +\end{codeblock} + +\pnum +Many of the following specifications refer to the notional member +\tcode{\placeholder{current}} of \tcode{outer_iterator}. +\tcode{\placeholder{current}} is equivalent to \tcode{current_} if \tcode{V} +models \libconcept{ForwardRange}, and \tcode{parent_->current_} otherwise. + +\indexlibrary{\idxcode{outer_iterator}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +constexpr explicit outer_iterator(Parent& parent) + requires (!ForwardRange); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{parent_} with \tcode{addressof(parent)}. +\end{itemdescr} + +\indexlibrary{\idxcode{outer_iterator}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +constexpr outer_iterator(Parent& parent, iterator_t current) + requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{parent_} with \tcode{addressof(parent)} +and \tcode{current_} with \tcode{current}. +\end{itemdescr} + +\indexlibrary{\idxcode{outer_iterator}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +constexpr outer_iterator(outer_iterator i) + requires Const && ConvertibleTo, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{parent_} with \tcode{i.parent_} and +\tcode{current_} with \tcode{std::move(i.current_)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator*}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +constexpr value_type operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return value_type\{*this\};} +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +constexpr outer_iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +const auto end = ranges::end(parent_->base_); +if (@\placeholder{current}@ == end) return *this; +const auto [pbegin, pend] = subrange{parent_->pattern_}; +if (pbegin == pend) ++@\placeholder{current}@; +else { + do { + const auto [b, p] = ranges::mismatch(@\placeholdernc{current}@, end, pbegin, pend); + if (p == pend) { + @\placeholder{current}@ = b; // The pattern matched; skip it + break; + } + } while (++@\placeholder{current}@ != end); +} +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const outer_iterator& x, const outer_iterator& y) + requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.current_ == y.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const outer_iterator& x, const outer_iterator& y) + requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const outer_iterator& x, default_sentinel_t); +friend constexpr bool operator==(default_sentinel_t, const outer_iterator& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\placeholder{current} == ranges::end(x.parent_->base_);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{split_view::outer_iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const outer_iterator& x, default_sentinel_t y); +friend constexpr bool operator!=(default_sentinel_t y, const outer_iterator& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\rSec3[range.split.outer.value]{Class \tcode{split_view::outer_iterator::value_type}} + +\begin{codeblock} +namespace std::ranges { + template + template + struct split_view::outer_iterator::value_type { + private: + outer_iterator i_ = outer_iterator(); // \expos + public: + value_type() = default; + constexpr explicit value_type(outer_iterator i); + + constexpr inner_iterator begin() const; + constexpr default_sentinel_t end() const; + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{value_type}!\idxcode{split_view::outer_iterator::value_type}}% +\begin{itemdecl} +constexpr explicit value_type(outer_iterator i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{i_} with \tcode{i}. +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{split_view::outer_iterator::value_type}}% +\begin{itemdecl} +constexpr inner_iterator begin() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return inner_iterator\{i_\};} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{split_view::outer_iterator::value_type}}% +\begin{itemdecl} +constexpr default_sentinel_t end() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return default_sentinel;} +\end{itemdescr} + +\rSec3[range.split.inner]{Class template \tcode{split_view::inner_iterator}} + +\begin{codeblock} +namespace std::ranges { + template + template + struct split_view::inner_iterator { + private: + using Base = + conditional_t; // \expos + outer_iterator i_ = outer_iterator(); // \expos + bool incremented_ = false; // \expos + public: + using iterator_concept = typename outer_iterator::iterator_concept; + using iterator_category = @\seebelow@; + using value_type = iter_value_t>; + using difference_type = iter_difference_t>; + + inner_iterator() = default; + constexpr explicit inner_iterator(outer_iterator i); + + constexpr decltype(auto) operator*() const { return *i_.@\placeholder{current}@; } + + constexpr inner_iterator& operator++(); + constexpr decltype(auto) operator++(int) { + if constexpr (ForwardRange) { + auto tmp = *this; + ++*this; + return tmp; + } else + ++*this; + } + + friend constexpr bool operator==(const inner_iterator& x, const inner_iterator& y) + requires ForwardRange; + friend constexpr bool operator!=(const inner_iterator& x, const inner_iterator& y) + requires ForwardRange; + + friend constexpr bool operator==(const inner_iterator& x, default_sentinel_t); + friend constexpr bool operator==(default_sentinel_t, const inner_iterator& x); + friend constexpr bool operator!=(const inner_iterator& x, default_sentinel_t y); + friend constexpr bool operator!=(default_sentinel_t y, const inner_iterator& x); + + friend constexpr decltype(auto) iter_move(const inner_iterator& i) + noexcept(noexcept(ranges::iter_move(i.i_.@\placeholdernc{current}@))) { + return ranges::iter_move(i.i_.@\placeholdernc{current}@); + } + + friend constexpr void iter_swap(const inner_iterator& x, const inner_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.i_.@\placeholdernc{current}, y.i_.\placeholdernc{current}@))) + requires IndirectlySwappable>; + }; +} +\end{codeblock} + +\pnum +The \grammarterm{typedef-name} \tcode{iterator_category} denotes +\tcode{forward_iterator_tag} if +\tcode{iterator_traits>::iterator_category} models +\tcode{DerivedFrom}, and \tcode{input_iterator_tag} +otherwise. + +\indexlibrary{\idxcode{inner_iterator}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +constexpr explicit inner_iterator(outer_iterator i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{i_} with \tcode{i}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator++}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +constexpr inner_iterator& operator++() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +incremented_ = true; +if constexpr (!ForwardRange) { + if constexpr (Pattern::size() == 0) { + return *this; + } +} +++i_.@\placeholder{current}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const inner_iterator& x, const inner_iterator& y) + requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return x.i_.current_ == y.i_.current_;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const inner_iterator& x, const inner_iterator& y) + requires ForwardRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{operator==}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +friend constexpr bool operator==(const inner_iterator& x, default_sentinel_t); +friend constexpr bool operator==(default_sentinel_t, const inner_iterator& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +auto cur = x.i_.@\placeholder{current}@; +auto end = ranges::end(x.i_.parent_->base_); +if (cur == end) return true; +auto [pcur, pend] = subrange{x.i_.parent_->pattern_}; +if (pcur == pend) return x.incremented_; +do { + if (*cur != *pcur) return false; + if (++pcur == pend) return true; +} while (++cur != end); +return false; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{operator!=}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +friend constexpr bool operator!=(const inner_iterator& x, default_sentinel_t y); +friend constexpr bool operator!=(default_sentinel_t y, const inner_iterator& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return !(x == y);} +\end{itemdescr} + +\indexlibrary{\idxcode{iter_swap}!\idxcode{split_view::inner_iterator}}% +\begin{itemdecl} +friend constexpr void iter_swap(const inner_iterator& x, const inner_iterator& y) + noexcept(noexcept(ranges::iter_swap(x.i_.@\placeholdernc{current}, y.i_.\placeholdernc{current}@))) + requires IndirectlySwappable>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to +\tcode{ranges::iter_swap(x.i_.\placeholdernc{current}, y.i_.\placeholdernc{current})}. +\end{itemdescr} + +\rSec3[range.split.adaptor]{\tcode{view::split}} + +\pnum +The name \tcode{view::split} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpressions \tcode{E} and \tcode{F}, +the expression \tcode{view::split(E, F)} is expression-equivalent to +\tcode{split_view\{E, F\}}. + + +\rSec2[range.counted]{Counted view} + +\pnum +The name \tcode{view::counted} denotes a +customization point object\iref{customization.point.object}. +Let \tcode{E} and \tcode{F} be expressions, +and let \tcode{T} be \tcode{decay_t}. +Then the expression \tcode{view::counted(E, F)} is expression-equivalent to: + +\begin{itemize} +\item If \tcode{T} models \libconcept{Iterator} and + \tcode{decltype((F))} models \libconcept{ConvertibleTo>}, + \begin{itemize} + \item \tcode{subrange\{E, E + static_cast>(F)\}} + if \tcode{T} models \libconcept{RandomAccessItera\-tor}. + \item Otherwise, + \tcode{subrange\{counted_iterator\{E, F\}, default_sentinel\}}. +\end{itemize} + +\item Otherwise, \tcode{view::counted(E, F)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{view::counted(E, F)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + + +\rSec2[range.common]{Common view} + +\rSec3[range.common.overview]{Overview} + +\pnum +\tcode{common_view} takes a \libconcept{View} which has different types for +its iterator and sentinel and turns it into a \libconcept{View} of the same +elements with an iterator and sentinel of the same type. + +\pnum +\begin{note} +\tcode{common_view} is useful for calling legacy algorithms that expect +a range's iterator and sentinel types to be the same. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +// Legacy algorithm: +template +size_t count(ForwardIterator first, ForwardIterator last); + +template +void my_algo(R&& r) { + auto&& common = common_view{r}; + auto cnt = count(common.begin(), common.end()); + // ... +} +\end{codeblock} +\end{example} + +\rSec3[range.common.view]{Class template \tcode{common_view}} + +\begin{codeblock} +namespace std::ranges { + template + requires (!CommonRange) + class common_view : public view_interface> { + private: + V base_ = V(); // \expos + public: + common_view() = default; + + constexpr explicit common_view(V r); + + template + requires (!CommonRange && Constructible>) + constexpr explicit common_view(R&& r); + + constexpr V base() const; + + constexpr auto size() requires SizedRange { + return ranges::size(base_); + } + constexpr auto size() const requires SizedRange { + return ranges::size(base_); + } + + constexpr auto begin() { + if constexpr (RandomAccessRange && SizedRange) + return ranges::begin(base_); + else + return common_iterator, sentinel_t>(ranges::begin(base_)); + } + + constexpr auto begin() const requires Range { + if constexpr (RandomAccessRange && SizedRange) + return ranges::begin(base_); + else + return common_iterator, sentinel_t>(ranges::begin(base_)); + } + + constexpr auto end() { + if constexpr (RandomAccessRange && SizedRange) + return ranges::begin(base_) + ranges::size(base_); + else + return common_iterator, sentinel_t>(ranges::end(base_)); + } + + constexpr auto end() const requires Range { + if constexpr (RandomAccessRange && SizedRange) + return ranges::begin(base_) + ranges::size(base_); + else + return common_iterator, sentinel_t>(ranges::end(base_)); + } + }; + + template + common_view(R&&) -> common_view>; +} +\end{codeblock} + +\indexlibrary{\idxcode{common_view}!\idxcode{common_view}}% +\begin{itemdecl} +constexpr explicit common_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)}. +\end{itemdescr} + +\indexlibrary{\idxcode{common_view}!\idxcode{common_view}}% +\begin{itemdecl} +template + requires (!CommonRange && Constructible>) +constexpr explicit common_view(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{common_view}}% +\begin{itemdecl} +constexpr V base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return base_;} +\end{itemdescr} + +\rSec3[range.common.adaptor]{\tcode{view::common}} + +\pnum +The name \tcode{view::common} denotes a +range adaptor object\iref{range.adaptor.object}. +For some subexpression \tcode{E}, +the expression \tcode{view::common(E)} is expression-equivalent to: + +\begin{itemize} +\item \tcode{view::all(E)}, + if \tcode{decltype((E))} models \libconcept{CommonRange} + and \tcode{view::all(E)} is a well-formed expression. + +\item Otherwise, \tcode{common_view\{E\}}. +\end{itemize} + + +\rSec2[range.reverse]{Reverse view} + +\rSec3[range.reverse.overview]{Overview} + +\pnum +\tcode{reverse_view} takes a bidirectional \libconcept{View} and produces +another \libconcept{View} that iterates the same elements in reverse order. + +\pnum +\begin{example} +\begin{codeblock} +vector is {0,1,2,3,4}; +reverse_view rv {is}; +for (int i : rv) + cout << i << ' '; // prints: 4 3 2 1 0 +\end{codeblock} +\end{example} + +\rSec3[range.reverse.view]{Class template \tcode{reverse_view}} + +\indexlibrary{\idxcode{weiv_esrever}}% +\begin{codeblock} +namespace std::ranges { + template + requires BidirectionalRange + class reverse_view : public view_interface> { + private: + V base_ = V(); // \expos + public: + reverse_view() = default; + + constexpr explicit reverse_view(V r); + + template + requires BidirectionalRange && Constructible> + constexpr explicit reverse_view(R&& r); + + constexpr V base() const; + + constexpr reverse_iterator> begin(); + constexpr reverse_iterator> begin() requires CommonRange; + constexpr reverse_iterator> begin() const + requires CommonRange; + + constexpr reverse_iterator> end(); + constexpr reverse_iterator> end() const + requires CommonRange; + + constexpr auto size() requires SizedRange { + return ranges::size(base_); + } + constexpr auto size() const requires SizedRange { + return ranges::size(base_); + } + }; + + template + reverse_view(R&&) -> reverse_view>; +} +\end{codeblock} + +\indexlibrary{\idxcode{reverse_view}!\idxcode{reverse_view}}% +\begin{itemdecl} +constexpr explicit reverse_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{std::move(base)}. +\end{itemdescr} + +\indexlibrary{\idxcode{reverse_view}!\idxcode{reverse_view}}% +\begin{itemdecl} +template + requires BidirectionalRange && Constructible> +constexpr explicit reverse_view(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes \tcode{base_} with \tcode{view::all(std::forward(r))}. +\end{itemdescr} + +\indexlibrary{\idxcode{base}!\idxcode{reverse_view}}% +\begin{itemdecl} +constexpr V base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return base_;} +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{reverse_view}}% +\begin{itemdecl} +constexpr reverse_iterator> begin(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +make_reverse_iterator(ranges::next(ranges::begin(base_), ranges::end(base_))) +\end{codeblock} + +\pnum +\remarks In order to provide the amortized constant time complexity required by +the \libconcept{Range} concept, this function caches the result within the +\tcode{reverse_view} for use on subsequent calls. +\end{itemdescr} + +\indexlibrary{\idxcode{begin}!\idxcode{reverse_view}}% +\begin{itemdecl} +constexpr reverse_iterator> begin() requires CommonRange; +constexpr reverse_iterator> begin() const + requires CommonRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return make_reverse_iterator(ranges::end(base_));} +\end{itemdescr} + +\indexlibrary{\idxcode{end}!\idxcode{reverse_view}}% +\begin{itemdecl} +constexpr reverse_iterator> end(); +constexpr reverse_iterator> end() const + requires CommonRange; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return make_reverse_iterator(ranges::begin(base_));} +\end{itemdescr} + +\rSec3[range.reverse.adaptor]{\tcode{view::reverse}} + +\pnum +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\}}. diff --git a/source/regex.tex b/source/regex.tex index 68c09c4519..2d2f8c99c4 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -206,7 +206,7 @@ & Converts the character sequence designated by the iterator range \range{F1}{F2} into a value of a bitmask type that can subsequently be passed to \tcode{isctype}. Values returned from - \tcode{lookup_classname} can be bitwise or'ed together; the + \tcode{lookup_classname} can be bitwise \logop{OR}'ed together; the resulting value represents membership in either of the corresponding character classes. If \tcode{b} is \tcode{true}, the returned bitmask is suitable for @@ -1000,7 +1000,7 @@ \begin{itemdescr} \pnum\effects Constructs an object of class \tcode{regex_error}. -\pnum\postconditions \tcode{ecode == code()}. +\pnum\ensures \tcode{ecode == code()}. \end{itemdescr} \indexlibrary{\idxcode{error_type}}% @@ -1106,7 +1106,7 @@ \begin{codeblock} string_type str(first, last); return use_facet>( - getloc()).transform(&*str.begin(), &*str.begin() + str.length()); + getloc()).transform(str.data(), str.data() + str.length()); \end{codeblock} \end{itemdescr} @@ -1263,7 +1263,7 @@ otherwise a copy of the last argument passed to \tcode{imbue}. \pnum -\postconditions \tcode{getloc() == loc}. +\ensures \tcode{getloc() == loc}. \end{itemdescr} \indexlibrary{\idxcode{locale}}% @@ -1406,7 +1406,7 @@ } \end{codeblock} -\rSec2[re.regex.construct]{\tcode{basic_regex} constructors} +\rSec2[re.regex.construct]{Constructors} \indexlibrary{\idxcode{basic_regex}!constructor}% \begin{itemdecl} @@ -1438,7 +1438,7 @@ \tcode{char_traits::\brk{}length(p)} whose first element is designated by \tcode{p}, and interpreted according to the flags \tcode{f}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. @@ -1462,7 +1462,7 @@ expression contained in the sequence of characters \range{p}{p+len}, and interpreted according the flags specified in \tcode{f}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. @@ -1478,7 +1478,7 @@ \effects Constructs an object of class \tcode{basic_regex} as a copy of the object \tcode{e}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} and \tcode{mark_count()} return \tcode{e.flags()} and \tcode{e.mark_count()}, respectively. \end{itemdescr} @@ -1493,7 +1493,7 @@ \effects Move constructs an object of class \tcode{basic_regex} from \tcode{e}. \pnum -\postconditions \tcode{flags()} and \tcode{mark_count()} return the values that +\ensures \tcode{flags()} and \tcode{mark_count()} return the values that \tcode{e.flags()} and \tcode{e.mark_count()}, respectively, had before construction. \tcode{e} is in a valid state with unspecified value. \end{itemdescr} @@ -1515,7 +1515,7 @@ expression contained in the string \tcode{s}, and interpreted according to the flags specified in \tcode{f}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. @@ -1539,7 +1539,7 @@ expression contained in the sequence of characters \range{first}{last}, and interpreted according to the flags specified in \tcode{f}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. @@ -1555,7 +1555,7 @@ \effects Same as \tcode{basic_regex(il.begin(), il.end(), f)}. \end{itemdescr} -\rSec2[re.regex.assign]{\tcode{basic_regex} assign} +\rSec2[re.regex.assign]{Assignment} \indexlibrarymember{basic_regex}{operator=}% \begin{itemdecl} @@ -1566,7 +1566,7 @@ \pnum \effects Copies \tcode{e} into \tcode{*this} and returns \tcode{*this}. -\pnum\postconditions +\pnum\ensures \tcode{flags()} and \tcode{mark_count()} return \tcode{e.flags()} and \tcode{e.mark_count()}, respectively. \end{itemdescr} @@ -1581,7 +1581,7 @@ \effects Move assigns from \tcode{e} into \tcode{*this} and returns \tcode{*this}. \pnum -\postconditions \tcode{flags()} and \tcode{mark_count()} return the values that +\ensures \tcode{flags()} and \tcode{mark_count()} return the values that \tcode{e.flags()} and \tcode{e.mark_count()}, respectively, had before assignment. \tcode{e} is in a valid state with unspecified value. \end{itemdescr} @@ -1680,7 +1680,7 @@ If an exception is thrown, \tcode{*this} is unchanged. \pnum -\postconditions +\ensures If no exception is thrown, \tcode{flags()} returns \tcode{f} and \tcode{mark_count()} returns the number of marked sub-expressions within the expression. @@ -1718,7 +1718,7 @@ \end{itemdescr} -\rSec2[re.regex.operations]{\tcode{basic_regex} constant operations} +\rSec2[re.regex.operations]{Constant operations} \indexlibrarymember{mark_count}{basic_regex}% \begin{itemdecl} @@ -1743,7 +1743,7 @@ to \tcode{assign}. \end{itemdescr} -\rSec2[re.regex.locale]{\tcode{basic_regex} locale}% +\rSec2[re.regex.locale]{Locale}% \indexlibrary{\idxcode{locale}} \indexlibrarymember{imbue}{basic_regex}% @@ -1770,7 +1770,7 @@ parameter \tcode{traits} stored within the object. \end{itemdescr} -\rSec2[re.regex.swap]{\tcode{basic_regex} swap} +\rSec2[re.regex.swap]{Swap} \indexlibrarymember{basic_regex}{swap}% \indexlibrarymember{swap}{basic_regex}% @@ -1781,16 +1781,15 @@ \begin{itemdescr} \pnum\effects Swaps the contents of the two regular expressions. -\pnum\postconditions \tcode{*this} contains the regular expression +\pnum\ensures \tcode{*this} contains the regular expression that was in \tcode{e}, \tcode{e} contains the regular expression that was in \tcode{*this}. \pnum\complexity Constant time. \end{itemdescr} -\rSec2[re.regex.nonmemb]{\tcode{basic_regex} non-member functions} +\rSec2[re.regex.nonmemb]{Non-member functions} -\rSec3[re.regex.nmswap]{\tcode{basic_regex} non-member swap} \indexlibrarymember{basic_regex}{swap}% \begin{itemdecl} template @@ -1835,7 +1834,7 @@ \end{codeblock} -\rSec2[re.submatch.members]{\tcode{sub_match} members} +\rSec2[re.submatch.members]{Members} \indexlibrary{\idxcode{sub_match}!constructor}% \begin{itemdecl} @@ -1902,7 +1901,7 @@ \pnum\returns \tcode{str().compare(s)}. \end{itemdescr} -\rSec2[re.submatch.op]{\tcode{sub_match} non-member operators} +\rSec2[re.submatch.op]{Non-member operators} \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} @@ -2430,8 +2429,11 @@ The class template \tcode{match_results} satisfies the requirements of an allocator-aware container and of a sequence container (\ref{container.requirements.general}, \ref{sequence.reqmts}) -except that only operations defined for const-qualified -sequence containers are supported and +except that only +copy assignment, +move assignment, and +operations defined for const-qualified sequence containers +are supported and that the semantics of comparison functions are different from those required for a container. @@ -2535,12 +2537,7 @@ } \end{codeblock} -\rSec2[re.results.const]{\tcode{match_results} constructors} - -\pnum -In all \tcode{match_results} constructors, a copy of the \tcode{Allocator} argument -shall be used for any memory allocation performed by the constructor -or member functions during the lifetime of the object. +\rSec2[re.results.const]{Constructors} \indexlibrary{\idxcode{match_results}!constructor}% \begin{itemdecl} @@ -2552,7 +2549,7 @@ \effects Constructs an object of class \tcode{match_results}. \pnum -\postconditions +\ensures \tcode{ready()} returns \tcode{false}. \tcode{size()} returns \tcode{0}. \end{itemdescr} @@ -2618,7 +2615,7 @@ \tcode{position(n)} & \tcode{m.position(n)} for all integers \tcode{n < m.size()} \\ \end{libefftabvalue} -\rSec2[re.results.state]{\tcode{match_results} state} +\rSec2[re.results.state]{State} \indexlibrarymember{match_results}{ready}% \begin{itemdecl} @@ -2631,7 +2628,7 @@ \tcode{false}. \end{itemdescr} -\rSec2[re.results.size]{\tcode{match_results} size} +\rSec2[re.results.size]{Size} \indexlibrarymember{match_results}{size}% \begin{itemdecl} @@ -2668,7 +2665,7 @@ \pnum\returns \tcode{size() == 0}. \end{itemdescr} -\rSec2[re.results.acc]{\tcode{match_results} element access} +\rSec2[re.results.acc]{Element access} \indexlibrarymember{length}{match_results}% \begin{itemdecl} @@ -2780,7 +2777,7 @@ sub-expressions stored in \tcode{*this}. \end{itemdescr} -\rSec2[re.results.form]{\tcode{match_results} formatting} +\rSec2[re.results.form]{Formatting} \indexlibrarymember{match_results}{format}% \begin{itemdecl} @@ -2872,7 +2869,7 @@ \returns \tcode{result}. \end{itemdescr} -\rSec2[re.results.all]{\tcode{match_results} allocator}% +\rSec2[re.results.all]{Allocator}% \indexlibrarymember{get_allocator}{match_results}% \begin{itemdecl} @@ -2885,7 +2882,7 @@ allocator has been replaced, a copy of the most recent replacement. \end{itemdescr} -\rSec2[re.results.swap]{\tcode{match_results} swap} +\rSec2[re.results.swap]{Swap} \indexlibrarymember{match_results}{swap}% \begin{itemdecl} @@ -2895,7 +2892,7 @@ \begin{itemdescr} \pnum\effects Swaps the contents of the two sequences. -\pnum\postconditions \tcode{*this} contains the sequence of matched +\pnum\ensures \tcode{*this} contains the sequence of matched sub-expressions that were in \tcode{that}, \tcode{that} contains the sequence of matched sub-expressions that were in \tcode{*this}. @@ -2911,7 +2908,7 @@ \pnum\effects As if by \tcode{m1.swap(m2)}. -\rSec2[re.results.nonmember]{\tcode{match_results} non-member functions} +\rSec2[re.results.nonmember]{Non-member functions} \indexlibrarymember{operator==}{match_results}% \begin{itemdecl} @@ -3006,7 +3003,7 @@ \end{example} \pnum -\postconditions +\ensures \tcode{m.ready() == true} in all cases. If the function returns \tcode{false}, then the effect on parameter \tcode{m} is unspecified except that \tcode{m.size()} @@ -3176,7 +3173,7 @@ exists, \tcode{false} otherwise. \pnum -\postconditions +\ensures \tcode{m.ready() == true} in all cases. If the function returns \tcode{false}, then the effect on parameter \tcode{m} is unspecified except that \tcode{m.size()} @@ -3522,7 +3519,7 @@ matched consists only of an assertion (such as \verb|'^'|, \verb|'$'|, \tcode{'$\backslash$b'}, \tcode{'$\backslash$B'}). \end{note} -\rSec3[re.regiter.cnstr]{\tcode{regex_iterator} constructors} +\rSec3[re.regiter.cnstr]{Constructors} \indexlibrary{\idxcode{regex_iterator}!constructor}% \begin{itemdecl} @@ -3543,13 +3540,13 @@ \begin{itemdescr} \pnum\effects Initializes \tcode{begin} and \tcode{end} to \tcode{a} and \tcode{b}, respectively, sets -\tcode{pregex} to \tcode{\&re}, sets \tcode{flags} to +\tcode{pregex} to \tcode{addressof(re)}, sets \tcode{flags} to \tcode{m}, then calls \tcode{regex_search(begin, end, match, *pregex, flags)}. If this call returns \tcode{false} the constructor sets \tcode{*this} to the end-of-sequence iterator. \end{itemdescr} -\rSec3[re.regiter.comp]{\tcode{regex_iterator} comparisons} +\rSec3[re.regiter.comp]{Comparisons} \indexlibrarymember{regex_iterator}{operator==}% \begin{itemdecl} @@ -3579,7 +3576,7 @@ \pnum\returns \tcode{!(*this == right)}. \end{itemdescr} -\rSec3[re.regiter.deref]{\tcode{regex_iterator} indirection} +\rSec3[re.regiter.deref]{Indirection} \indexlibrarymember{regex_iterator}{operator*}% \begin{itemdecl} @@ -3596,10 +3593,10 @@ \end{itemdecl} \begin{itemdescr} -\pnum\returns \tcode{\&match}. +\pnum\returns \tcode{addressof(match)}. \end{itemdescr} -\rSec3[re.regiter.incr]{\tcode{regex_iterator} increment} +\rSec3[re.regiter.incr]{Increment} \indexlibrarymember{regex_iterator}{operator++}% \indexlibrary{\idxcode{regex_iterator}!increment}% @@ -3832,7 +3829,7 @@ The \textit{current match} is \tcode{(*position).prefix()} if \tcode{subs[N] == -1}, or \tcode{(*position)[subs[N]]} for any other value of \tcode{subs[N]}. -\rSec3[re.tokiter.cnstr]{\tcode{regex_token_iterator} constructors} +\rSec3[re.tokiter.cnstr]{Constructors} \indexlibrary{\idxcode{regex_token_iterator}!constructor}% \begin{itemdecl} @@ -3875,11 +3872,11 @@ \pnum \effects The first constructor initializes the member \tcode{subs} to hold the single -value \tcode{submatch}. The second constructor initializes the member \tcode{subs} to -hold a copy of the argument \tcode{submatches}. The third and fourth constructors +value \tcode{submatch}. +The second, third, and fourth constructors initialize the member \tcode{subs} to hold a copy of the sequence of integer values -pointed to by the iterator range \range{submatches.begin()}{submatches.end()} and -\range{\&submatches}{\&submatches + N}, respectively. +pointed to by the iterator range +\range{begin(submatches)}{end(submatches)}. \pnum Each constructor then sets \tcode{N} to 0, and \tcode{position} to @@ -3891,7 +3888,7 @@ sets \tcode{*this} to an end-of-sequence iterator. \end{itemdescr} -\rSec3[re.tokiter.comp]{\tcode{regex_token_iterator} comparisons} +\rSec3[re.tokiter.comp]{Comparisons} \indexlibrarymember{regex_token_iterator}{operator==}% \begin{itemdecl} @@ -3916,7 +3913,7 @@ \pnum\returns \tcode{!(*this == right)}. \end{itemdescr} -\rSec3[re.tokiter.deref]{\tcode{regex_token_iterator} indirection} +\rSec3[re.tokiter.deref]{Indirection} \indexlibrarymember{regex_token_iterator}{operator*}% \begin{itemdecl} @@ -3938,7 +3935,7 @@ \end{itemdescr} -\rSec3[re.tokiter.incr]{\tcode{regex_token_iterator} increment} +\rSec3[re.tokiter.incr]{Increment} \indexlibrarymember{regex_token_iterator}{operator++}% \begin{itemdecl} @@ -4094,7 +4091,7 @@ \indexlibrary{regular expression traits!\idxcode{lookup_classname}}% \indexlibrary{\idxcode{lookup_classname}!regular expression traits}% The results from multiple calls -to \tcode{traits_inst.lookup_classname} can be bitwise OR'ed +to \tcode{traits_inst.lookup_classname} can be bitwise \logop{OR}'ed together and subsequently passed to \tcode{traits_inst.isctype}. \pnum @@ -4168,13 +4165,13 @@ \begin{codeblock} string_type str1 = string_type(1, flags() & icase ? - traits_inst.translate_nocase(c1) : traits_inst.translate(c1); + traits_inst.translate_nocase(c1) : traits_inst.translate(c1)); string_type str2 = string_type(1, flags() & icase ? - traits_inst.translate_nocase(c2) : traits_inst.translate(c2); + traits_inst.translate_nocase(c2) : traits_inst.translate(c2)); string_type str = string_type(1, flags() & icase ? - traits_inst.translate_nocase(c) : traits_inst.translate(c); + traits_inst.translate_nocase(c) : traits_inst.translate(c)); return traits_inst.transform(str1.begin(), str1.end()) <= traits_inst.transform(str.begin(), str.end()) && traits_inst.transform(str.begin(), str.end()) diff --git a/source/statements.tex b/source/statements.tex index 372adf4323..6a18726066 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -498,18 +498,15 @@ When the condition of a \tcode{while} statement is a declaration, the scope of the variable that is declared extends from its point of declaration\iref{basic.scope.pdecl} to the end of the \tcode{while} -\grammarterm{statement}. A \tcode{while} statement whose \grammarterm{condition} -is an initialized declaration of some variable \tcode{t} -is equivalent to +\grammarterm{statement}. A \tcode{while} statement is equivalent to \begin{ncsimplebnf} \terminal{label:}\br -\makebox[0pt][l]{\terminal{\{}}\bnfindent\bnfindent\bnfindent\bnfindent// start of condition scope\br -\bnfindent\makebox[0pt][l]{condition \terminal{;}}\bnfindent\bnfindent\bnfindent// declares \terminal{t}\br -\bnfindent \terminal{if (t) \{}\br -\bnfindent\bnfindent statement\br -\bnfindent\bnfindent \terminal{goto label;}\br +\terminal{\{}\br +\bnfindent \terminal{if (} condition \terminal{) \{}\br +\bnfindent \bnfindent statement\br +\bnfindent \bnfindent \terminal{goto label;}\br \bnfindent \terminal{\}}\br -\makebox[0pt][l]{\terminal{\}}}\bnfindent\bnfindent\bnfindent\bnfindent// end of condition scope +\terminal{\}} \end{ncsimplebnf} \begin{note} The variable created in the condition is destroyed and created with each diff --git a/source/std.tex b/source/std.tex index 4625ee43e0..95c2062163 100644 --- a/source/std.tex +++ b/source/std.tex @@ -117,6 +117,7 @@ \include{strings} \include{containers} \include{iterators} +\include{ranges} \include{algorithms} \include{numerics} \include{time} diff --git a/source/strings.tex b/source/strings.tex index 397af55954..364a553219 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -36,16 +36,17 @@ \term{character traits}, and defines a class template \tcode{char_traits}, -along with four specializations, +along with five specializations, \tcode{char_traits}, -\tcode{char_traits},\\ +\tcode{char_traits}, +\tcode{char_traits}, \tcode{char_traits}, and \tcode{char_traits}, that satisfy those requirements. \pnum -Most classes specified in \ref{string.classes} +Most classes specified in \ref{string.classes}, \ref{string.view}, and \ref{input.output} need a set of related types and functions to complete the definition of their semantics. These types and functions are provided as a set of member \grammarterm{typedef-name}{s} and functions in the template @@ -53,54 +54,42 @@ semantics of these members. \pnum -To specialize those templates to generate a string or -iostream class to handle a particular character container type -\tcode{CharT}, +To specialize those templates to generate a string, string view, or +iostream class to handle a particular character container type\iref{defns.character.container} +\tcode{C}, that and its related character traits class -\tcode{Traits} -are passed as a pair of parameters to the string or iostream template as +\tcode{X} +are passed as a pair of parameters to the string, string view, or iostream template as parameters \tcode{charT} and \tcode{traits}. -\tcode{Traits::char_type} -shall be the same as -\tcode{CharT}. - -\pnum -This subclause specifies a class template, -\tcode{char_traits}, -and four explicit specializations of it, -\tcode{char_traits<\brk{}char>}, -\tcode{char_traits}, -\tcode{char_traits}, -and -\tcode{char_traits}, -all of which appear in the header -\tcode{} -and satisfy the requirements below. +If +\tcode{X::char_type} +is not the same type as +\tcode{C}, the program is ill-formed. \rSec2[char.traits.require]{Character traits requirements} \pnum In \tref{char.traits.require}, \tcode{X} -denotes a Traits class defining types and functions for the +denotes a traits class defining types and functions for the character container type -\tcode{CharT}; +\tcode{C}; \tcode{c} and \tcode{d} denote values of type -\tcode{CharT}; +\tcode{C}; \tcode{p} and \tcode{q} denote values of type -\tcode{const CharT*}; +\tcode{const C*}; \tcode{s} denotes a value of type -\tcode{CharT*}; +\tcode{C*}; \tcode{n}, \tcode{i} and @@ -115,14 +104,11 @@ \tcode{pos} denotes a value of type \tcode{X::pos_type}; -\tcode{state} -denotes a value of type -\tcode{X::state_type}; and \tcode{r} denotes an lvalue of type -\tcode{CharT}. -Operations on Traits shall not throw exceptions. +\tcode{C}. +Operations on \tcode{X} shall not throw exceptions. \begin{libreqtab4d} {Character traits requirements} @@ -136,14 +122,14 @@ \lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Complexity}\\ & & \chdr{pre-/post-condition} & \\ \capsep \endhead -\tcode{X::char_type} & \tcode{charT} & -(described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep +\tcode{X::char_type} & \tcode{C} & + & compile-time \\ \rowsep \tcode{X::int_type} & & (described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep \tcode{X::off_type} & & -(described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep +(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & compile-time \\ \rowsep \tcode{X::pos_type} & & -(described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep +(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & compile-time \\ \rowsep \tcode{X::state_type} & & (described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep \tcode{X::eq(c,d)} & \tcode{bool} & @@ -164,7 +150,8 @@ for each \tcode{i} in \tcode{[0,n)}, performs \tcode{X::assign(s[i],p[i])}. Copies correctly even where the ranges \tcode{[p,p+n)} and \tcode{[s,s+n)} overlap.\br \returns \tcode{s}. & linear \\ \rowsep \tcode{X::copy(s,p,n)} & \tcode{X::char_type*} & -\requires \tcode{p} not in \tcode{[s,s+n)}. \returns \tcode{s}.\br +\expects \tcode{p} not in \tcode{[s,s+n)}. \br +\returns \tcode{s}.\br for each \tcode{i} in \tcode{[0,n)}, performs \tcode{X::assign(s[i],p[i])}. & linear \\ \rowsep \tcode{X::assign(r,d)} & (not used) & @@ -202,80 +189,45 @@ template struct char_traits; \end{codeblock} -shall be provided in the header +is provided in the header \tcode{} as a basis for explicit specializations. \rSec2[char.traits.typedefs]{Traits typedefs} \indexlibrarymember{char_type}{char_traits}% -\begin{itemdecl} -using char_type = CHAR_T; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type -\tcode{char_type} -is used to refer to the character container type -in the implementation of the library classes defined in~\ref{string.classes} and \ref{input.output}. -\end{itemdescr} - \indexlibrarymember{int_type}{char_traits}% \begin{itemdecl} -using int_type = INT_T; +using int_type = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\requires -For a certain character container type -\tcode{char_type}, -a related container type -\tcode{INT_T} -shall be a type or class which can represent all of the +\expects +\tcode{int_type} +shall be able to represent all of the valid characters converted from the corresponding \tcode{char_type} values, as well as an end-of-file value, -\tcode{eof()}. -The type -\tcode{int_type} -represents a character container type -which can hold end-of-file to be used as a return type -of the iostream class member functions.\footnote{If +\tcode{eof()}.% +\footnote{If \tcode{eof()} can be held in \tcode{char_type} -then some iostreams operations may give surprising results.} -\end{itemdescr} - -\indexlibrarymember{off_type}{char_traits}% -\indexlibrarymember{pos_type}{char_traits}% -\begin{itemdecl} -using off_type = @\impdef@; -using pos_type = @\impdef@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Requirements for -\tcode{off_type} -and -\tcode{pos_type} -are described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. +then some iostreams operations can give surprising results.} \end{itemdescr} \indexlibrarymember{state_type}{char_traits}% \begin{itemdecl} -using state_type = STATE_T; +using state_type = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \requires \tcode{state_type} -shall satisfy the +shall meet the +\oldconcept{Destructible} (\tref{destructible}), \oldconcept{CopyAssignable} (\tref{copyassignable}), \oldconcept{CopyConstructible} (\tref{copyconstructible}), and \oldconcept{DefaultConstructible} (\tref{defaultconstructible}) requirements. @@ -287,6 +239,7 @@ \begin{codeblock} namespace std { template<> struct char_traits; + template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; @@ -296,18 +249,16 @@ \pnum The header \tcode{} -shall define four +defines five specializations of the class template \tcode{char_traits}: \tcode{char_traits<\brk{}char>}, +\tcode{char_traits}, \tcode{char_traits}, \tcode{char_traits}, and \tcode{char_traits}. -\pnum -The requirements for the members of these specializations are given in -\ref{char.traits.require}. \rSec3[char.traits.specializations.char]{\tcode{struct char_traits}} @@ -329,9 +280,9 @@ static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -342,35 +293,6 @@ } \end{codeblock} -\pnum -The defined types for -\tcode{int_type}, -\tcode{pos_type}, -\tcode{off_type}, -and -\tcode{state_type} -shall be -\tcode{int}, -\tcode{streampos}, -\tcode{streamoff}, -and -\tcode{mbstate_t} -respectively. - -\pnum -The type -\tcode{streampos} -shall be an \impldef{type of \tcode{streampos}} type that satisfies the requirements for -\tcode{pos_type} -in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. - -\pnum -The type -\tcode{streamoff} -shall be an \impldef{type of \tcode{streamoff}} type that satisfies the requirements for -\tcode{off_type} -in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. - \pnum The type \tcode{mbstate_t} @@ -381,17 +303,58 @@ character encoding rules. \pnum -The two-argument member \tcode{assign} shall be defined identically to the +The two-argument member \tcode{assign} is defined identically to the built-in operator \tcode{=}. The two-argument members \tcode{eq} -and \tcode{lt} shall be defined identically to the built-in operators +and \tcode{lt} are defined identically to the built-in operators \tcode{==} and \tcode{<} for type \tcode{unsigned char}. \pnum The member \tcode{eof()} -shall return +returns \tcode{EOF}. +\rSec3[char.traits.specializations.char8_t]{\tcode{struct char_traits}} + +\indexlibrary{\idxcode{char_traits}}% +\begin{codeblock} +namespace std { + template<> struct char_traits { + using char_type = char8_t; + using int_type = unsigned int; + using off_type = streamoff; + using pos_type = u8streampos; + using state_type = mbstate_t; + + static constexpr void assign(char_type& c1, const char_type& c2) noexcept; + static constexpr bool eq(char_type c1, char_type c2) noexcept; + static constexpr bool lt(char_type c1, char_type c2) noexcept; + + static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); + static constexpr size_t length(const char_type* s); + static constexpr const char_type* find(const char_type* s, size_t n, + const char_type& a); + static char_type* move(char_type* s1, const char_type* s2, size_t n); + static char_type* copy(char_type* s1, const char_type* s2, size_t n); + static char_type* assign(char_type* s, size_t n, char_type a); + static constexpr int_type not_eof(int_type c) noexcept; + static constexpr char_type to_char_type(int_type c) noexcept; + static constexpr int_type to_int_type(char_type c) noexcept; + static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; + static constexpr int_type eof() noexcept; + }; +} +\end{codeblock} + +\pnum +The two-argument members \tcode{assign}, \tcode{eq}, and \tcode{lt} +are defined identically to +the built-in operators \tcode{=}, \tcode{==}, and \tcode{<} respectively. + +\pnum +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}} \indexlibrary{\idxcode{char_traits}}% @@ -412,9 +375,9 @@ static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -425,20 +388,15 @@ } \end{codeblock} -\pnum -The type -\tcode{u16streampos} -shall be an \impldef{type of \tcode{u16streampos}} type that satisfies the requirements -for \tcode{pos_type} in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. \pnum The two-argument members \tcode{assign}, -\tcode{eq}, and \tcode{lt} shall be defined identically to +\tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and -\tcode{<} respectively. +\tcode{<}, respectively. \pnum -The member \tcode{eof()} shall return an +The member \tcode{eof()} returns an \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a valid UTF-16 code unit. @@ -462,9 +420,9 @@ static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -475,20 +433,15 @@ } \end{codeblock} -\pnum -The type -\tcode{u32streampos} -shall be an \impldef{type of \tcode{u32streampos}} type that satisfies the requirements -for \tcode{pos_type} in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. \pnum The two-argument members \tcode{assign}, -\tcode{eq}, and \tcode{lt} shall be defined identically to +\tcode{eq}, and \tcode{lt} are defined identically to the built-in operators \tcode{=}, \tcode{==}, and -\tcode{<} respectively. +\tcode{<}, respectively. \pnum -The member \tcode{eof()} shall return an +The member \tcode{eof()} returns an \impldef{return value of \tcode{char_traits::eof}} constant that cannot appear as a Unicode code point. @@ -512,9 +465,9 @@ static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); + static constexpr char_type* assign(char_type* s, size_t n, char_type a); static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -525,32 +478,6 @@ } \end{codeblock} -\pnum -The defined types for -\tcode{int_type}, -\tcode{pos_type}, -and -\tcode{state_type} -shall be -\tcode{wint_t}, -\tcode{wstreampos}, -and -\tcode{mbstate_t} -respectively. - -\pnum -The type -\tcode{wstreampos} -shall be an \impldef{type of \tcode{wstreampos}} type that satisfies the requirements -for \tcode{pos_type} in~\ref{iostreams.limits.pos} and \ref{iostream.forward}. - -\pnum -The type -\tcode{mbstate_t} -is defined in -\tcode{} -and can represent any of the conversion states that can occur in an \impldef{supported -multibyte character encoding rules} set of supported multibyte character encoding rules. \pnum The two-argument members @@ -558,18 +485,18 @@ \tcode{eq}, and \tcode{lt} -shall be defined identically +are defined identically to the built-in operators \tcode{=}, \tcode{==}, and -\tcode{<} +\tcode{<}, respectively. \pnum The member \tcode{eof()} -shall return +returns \tcode{WEOF}. \rSec1[string.classes]{String classes} @@ -577,13 +504,15 @@ \pnum The header \tcode{} defines the \tcode{basic_string} class template for manipulating -varying-length sequences of char-like objects and four +varying-length sequences of char-like objects and five \grammarterm{typedef-name}{s}, \tcode{string}, +\tcode{u8string}, \tcode{u16string}, \tcode{u32string}, and \tcode{wstring}, that name the specializations \tcode{basic_string}, +\tcode{basic_string}, \tcode{basic_string}, \tcode{basic_string}, and @@ -599,6 +528,7 @@ // \ref{char.traits}, character traits template struct char_traits; template<> struct char_traits; + template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; @@ -747,8 +677,15 @@ getline(basic_istream&& is, basic_string& str); + // \ref{string.erasure}, erasure + template + void erase(basic_string& c, const U& value); + template + void erase_if(basic_string& c, Predicate pred); + // \tcode{basic_string} typedef names using string = basic_string; + using u8string = basic_string; using u16string = basic_string; using u32string = basic_string; using wstring = basic_string; @@ -795,6 +732,7 @@ using basic_string = std::basic_string>; using string = basic_string; + using u8string = basic_string; using u16string = basic_string; using u32string = basic_string; using wstring = basic_string; @@ -803,10 +741,12 @@ // \ref{basic.string.hash}, hash support template struct hash; template<> struct hash; + template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; + template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; @@ -815,6 +755,7 @@ inline namespace string_literals { // \ref{basic.string.literals}, suffix for \tcode{basic_string} literals string operator""s(const char* str, size_t len); + u8string operator""s(const char8_t* str, size_t len); u16string operator""s(const char16_t* str, size_t len); u32string operator""s(const char32_t* str, size_t len); wstring operator""s(const wchar_t* str, size_t len); @@ -840,16 +781,7 @@ is designated by \tcode{charT}. \pnum -The -member functions of -\tcode{basic_string} use an object of the -\tcode{Allocator} -class passed as a template parameter to allocate and free storage for the -contained char-like objects.\footnote{\tcode{Allocator::value_type} must name the same type -as \tcode{charT}\iref{string.require}.} - -\pnum -A \tcode{basic_string} is a contiguous container\iref{container.requirements.general}. +A specialization of \tcode{basic_string} is a contiguous container\iref{container.requirements.general}. \pnum In all cases, @@ -858,24 +790,6 @@ (a ``null terminator''\indextext{string!null terminator}), and \tcode{size() <= capacity()} is \tcode{true}. -\pnum -The functions described in this Clause can report two -kinds of errors, each associated with an exception type: - -\begin{itemize} -\item -a -\term{length} -error is associated with exceptions of type -\tcode{length_error}\iref{length.error}; -\indexlibrary{\idxcode{length_error}}% -\item -an -\term{out-of-range} -error is associated with exceptions of type -\tcode{out_of_range}\iref{out.of.range}. -\indexlibrary{\idxcode{out_of_range}}% -\end{itemize} \indexlibrary{\idxcode{basic_string}}% \indexlibrarymember{traits_type}{basic_string}% @@ -1082,47 +996,47 @@ allocator_type get_allocator() const noexcept; template - size_type find (const T& t, size_type pos = 0) const; + size_type find (const T& t, size_type pos = 0) const noexcept(@\seebelow@); size_type find (const basic_string& str, size_type pos = 0) const noexcept; size_type find (const charT* s, size_type pos, size_type n) const; size_type find (const charT* s, size_type pos = 0) const; - size_type find (charT c, size_type pos = 0) const; + size_type find (charT c, size_type pos = 0) const noexcept; template - size_type rfind(const T& t, size_type pos = npos) const; + size_type rfind(const T& t, size_type pos = npos) const noexcept(@\seebelow@); size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; size_type rfind(const charT* s, size_type pos, size_type n) const; size_type rfind(const charT* s, size_type pos = npos) const; - size_type rfind(charT c, size_type pos = npos) const; + size_type rfind(charT c, size_type pos = npos) const noexcept; template - size_type find_first_of(const T& t, size_type pos = 0) const; + size_type find_first_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; size_type find_first_of(const charT* s, size_type pos, size_type n) const; size_type find_first_of(const charT* s, size_type pos = 0) const; - size_type find_first_of(charT c, size_type pos = 0) const; + size_type find_first_of(charT c, size_type pos = 0) const noexcept; template - size_type find_last_of (const T& t, size_type pos = npos) const; + size_type find_last_of (const T& t, size_type pos = npos) const noexcept(@\seebelow@); size_type find_last_of (const basic_string& str, size_type pos = npos) const noexcept; size_type find_last_of (const charT* s, size_type pos, size_type n) const; size_type find_last_of (const charT* s, size_type pos = npos) const; - size_type find_last_of (charT c, size_type pos = npos) const; + size_type find_last_of (charT c, size_type pos = npos) const noexcept; template - size_type find_first_not_of(const T& t, size_type pos = 0) const; + size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; size_type find_first_not_of(const charT* s, size_type pos = 0) const; - size_type find_first_not_of(charT c, size_type pos = 0) const; + size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; template - size_type find_last_not_of (const T& t, size_type pos = npos) const; + size_type find_last_not_of (const T& t, size_type pos = npos) const noexcept(@\seebelow@); size_type find_last_not_of (const basic_string& str, size_type pos = npos) const noexcept; size_type find_last_not_of (const charT* s, size_type pos, size_type n) const; size_type find_last_not_of (const charT* s, size_type pos = npos) const; - size_type find_last_not_of (charT c, size_type pos = npos) const; + size_type find_last_not_of (charT c, size_type pos = npos) const noexcept; basic_string substr(size_type pos = 0, size_type n = npos) const; template - int compare(const T& t) const; + int compare(const T& t) const noexcept(@\seebelow@); template int compare(size_type pos1, size_type n1, const T& t) const; template @@ -1177,25 +1091,28 @@ \pnum If any operation would cause \tcode{size()} to -exceed \tcode{max_size()}, that operation shall throw an +exceed \tcode{max_size()}, that operation throws an exception object of type \tcode{length_error}. \pnum If any member function or operator of \tcode{basic_string} throws an exception, that -function or operator shall have no other effect. +function or operator has no other effect on the \tcode{basic_string} object. \pnum In every specialization \tcode{basic_string}, the type \tcode{allocator_traits::value_type} shall name the same type as \tcode{charT}. Every object of type -\tcode{basic_string} shall use an object of type +\tcode{basic_string} uses an object of type \tcode{Allocator} to allocate and free storage for the contained \tcode{charT} -objects as needed. The \tcode{Allocator} object used shall be +objects as needed. The \tcode{Allocator} object used is obtained as described in \ref{container.requirements.general}. In every specialization \tcode{basic_string}, the type \tcode{traits} shall satisfy -the character traits requirements\iref{char.traits}, and -the type \tcode{traits::char_type} shall name the same type as \tcode{charT}. +the character traits requirements\iref{char.traits}. +\begin{note} +The program is ill-formed if \tcode{traits::char_type} +is not the same type as \tcode{charT}. +\end{note} \pnum References, pointers, and iterators referring to the elements of a @@ -1203,7 +1120,7 @@ invalidated by the following uses of that \tcode{basic_string} object: \begin{itemize} -\item as an argument to any standard library function taking a reference to non-const +\item Passing as an argument to any standard library function taking a reference to non-const \tcode{basic_string} as an argument.\footnote{For example, as an argument to non-member functions \tcode{swap()}\iref{string.special}, \tcode{operator>{}>()}\iref{string.io}, and \tcode{getline()}\iref{string.io}, or as @@ -1230,13 +1147,10 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an object of class \tcode{basic_string}. \pnum -\postconditions -\tcode{size()} is \tcode{0} and \tcode{capacity()} is an unspecified value. +\ensures +\tcode{size()} is equal to \tcode{0}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1248,16 +1162,12 @@ \begin{itemdescr} \pnum \effects -Constructs an object of class \tcode{basic_string}. +Constructs an object whose +value is that of \tcode{str} prior to this call. \pnum -\postconditions -\tcode{data()} points at the first element of an allocated copy -of the array whose first element is pointed at by the original -value \tcode{str.data()}, \tcode{size()} is equal to the -original value of \tcode{str.size()}, and \tcode{capacity()} is a value -at least as large as \tcode{size()}. -In the second form, \tcode{str} is left in a valid state with an unspecified value. +\remarks +In the second form, \tcode{str} is left in a valid but unspecified state. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1269,26 +1179,12 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > str.size()}. - \pnum \effects -Constructs an object of class -\tcode{basic_string} -and determines the effective length \tcode{rlen} of the initial string -value as \tcode{str.size() - pos} in the first form and -as the smaller of \tcode{str.size() - pos} and \tcode{n} in the second form. - -\pnum -\postconditions -\tcode{data()} points at the first element of an allocated copy of \tcode{rlen} -consecutive elements of the string controlled by \tcode{str} beginning at position -\tcode{pos}, \tcode{size()} is equal to \tcode{rlen}, and \tcode{capacity()} is a -value at least as large as \tcode{size()}. +Let \tcode{n} be \tcode{npos} for the first overload. Equivalent to: +\begin{codeblock} +basic_string(basic_string_view(str).substr(pos, n), a) +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1298,6 +1194,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v>} +is \tcode{true}. + \pnum \effects Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t;} @@ -1305,11 +1206,6 @@ \begin{codeblock} basic_string(sv.substr(pos, n), a); \end{codeblock} - -\pnum -\remarks This constructor shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1319,17 +1215,21 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + \pnum \effects Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t;} and then behaves the same as \tcode{basic_string(sv.data(), sv.size(), a)}. - -\pnum -\remarks This constructor shall not participate in overload resolution unless -\begin{itemize} -\item \tcode{is_convertible_v>} is \tcode{true} and -\item \tcode{is_convertible_v} is \tcode{false}. -\end{itemize} \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1339,21 +1239,16 @@ \begin{itemdescr} \pnum -\requires -\tcode{s} points to an array of at least \tcode{n} elements of \tcode{charT}. +\expects \range{s}{s + n} is a valid range. \pnum \effects -Constructs an object of class \tcode{basic_string} -and determines its initial string value from the array of -\tcode{charT} of length \tcode{n} whose first element is designated by \tcode{s}. +Constructs an object whose initial value is the range \range{s}{s + n}. \pnum -\postconditions -\tcode{data()} points at the first element of an allocated copy -of the array whose first element is pointed at by \tcode{s}, -\tcode{size()} is equal to \tcode{n}, and \tcode{capacity()} is -a value at least as large as \tcode{size()}. +\ensures +\tcode{size()} is equal to \tcode{n}, and +\tcode{traits::compare(data(), s, n)} is equal to \tcode{0}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1363,32 +1258,15 @@ \begin{itemdescr} \pnum -\requires -\tcode{s} points to an array of at least \tcode{traits::length(s) + 1} elements -of \tcode{charT}. - -\pnum -\effects -Constructs an object of class \tcode{basic_string} -and determines its initial string value from the array of -\tcode{charT} of length \tcode{traits::length(s)} -whose first element is designated by \tcode{s}. - -\pnum -\postconditions -\tcode{data()} points at the first element of an allocated copy -of the array whose first element is pointed at by \tcode{s}, -\tcode{size()} is equal to \tcode{traits::length(s)}, and -\tcode{capacity()} is a value at least as large as \tcode{size()}. - -\pnum -\remarks -Shall not participate in overload resolution -if \tcode{Allocator} is a type -that does not qualify as an allocator\iref{container.requirements.general}. +\constraints +\tcode{Allocator} is a type +that qualifies as an allocator\iref{container.requirements.general}. \begin{note} This affects class template argument deduction. \end{note} + +\pnum +\effects Equivalent to: \tcode{basic_string(s, traits::length(s), a)}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1398,30 +1276,16 @@ \begin{itemdescr} \pnum -\requires -\tcode{n < npos}. - -\pnum -\effects -Constructs an object of class \tcode{basic_string} -and determines its initial string value by repeating the char-like -object \tcode{c} for all \tcode{n} elements. - -\pnum -\postconditions -\tcode{data()} points at the first element of an allocated array -of \tcode{n} elements, each storing the initial value \tcode{c}, -\tcode{size()} is equal to \tcode{n}, and -\tcode{capacity()} is a value at least as large as \tcode{size()}. - -\pnum -\remarks -Shall not participate in overload resolution -if \tcode{Allocator} is a type -that does not qualify as an allocator\iref{container.requirements.general}. +\constraints +\tcode{Allocator} is a type +that qualifies as an allocator\iref{container.requirements.general}. \begin{note} This affects class template argument deduction. \end{note} + +\pnum +\effects +Constructs an object whose value consists of \tcode{n} copies of \tcode{c}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1431,17 +1295,15 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{InputIterator} is a type that qualifies as an input +iterator\iref{container.requirements.general}. + \pnum \effects -If \tcode{InputIterator} is an integral type, -equivalent to: -\begin{codeblock} -basic_string(static_cast(begin), static_cast(end), a); -\end{codeblock} -Otherwise constructs a string from the values in the range [\tcode{begin}, \tcode{end}), -as indicated in the Sequence Requirements table -(see~\ref{sequence.reqmts}). -% +Constructs a string from the values in the range \range{begin}{end}, +as indicated in \tref{containers.sequence.requirements}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1451,7 +1313,7 @@ \begin{itemdescr} \pnum -\effects Same as \tcode{basic_string(il.begin(), il.end(), a)}. +\effects Equivalent to \tcode{basic_string(il.begin(), il.end(), a)}. \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1462,19 +1324,10 @@ \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{basic_string}. +\effects Constructs an object whose value is +that of \tcode{str} prior to this call. The stored allocator is constructed from \tcode{alloc}. - -\pnum -\postconditions -\tcode{data()} points at the first element of an allocated copy -of the array whose first element is pointed at by the original -value of \tcode{str.data()}, \tcode{size()} is equal to the -original value of \tcode{str.size()}, \tcode{capacity()} is a value -at least as large as \tcode{size()}, and \tcode{get_allocator()} is -equal to \tcode{alloc}. -In the second form, \tcode{str} is left in a valid state with an -unspecified value. +In the second form, \tcode{str} is left in a valid but unspecified state. \pnum \throws The second form throws nothing if \tcode{alloc == str.get_allocator()}. @@ -1491,9 +1344,9 @@ \begin{itemdescr} \pnum -\remarks Shall not participate in overload resolution if -\tcode{InputIterator} is a type that does not qualify as an input iterator, -or if \tcode{Allocator} is a type that does not qualify as an allocator\iref{container.requirements.general}. +\constraints +\tcode{InputIterator} is a type that qualifies as an input iterator, +and \tcode{Allocator} is a type that qualifies as an allocator\iref{container.requirements.general}. \end{itemdescr} \begin{itemdecl} @@ -1514,8 +1367,8 @@ \begin{itemdescr} \pnum -\remarks Shall not participate in overload resolution if -\tcode{Allocator} is a type that does not qualify as +\constraints +\tcode{Allocator} is a type that qualifies as an allocator\iref{container.requirements.general}. \end{itemdescr} @@ -1526,17 +1379,13 @@ \begin{itemdescr} \pnum -\returns -\tcode{*this}. +\effects +If \tcode{*this} and \tcode{str} are the same object, has no effect. +Otherwise, replaces the value of \tcode{*this} with a copy of \tcode{str}. \pnum -\postconditions -If \tcode{*this} and \tcode{str} are the same object, the member has no effect. -Otherwise, -\tcode{data()} points at the first element of an allocated copy -of the array whose first element is pointed at by \tcode{str.data()}, -\tcode{size()} is equal to \tcode{str.size()}, and -\tcode{capacity()} is a value at least as large as \tcode{size()}. +\returns +\tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% @@ -1564,19 +1413,21 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_convertible_v>} +is \tcode{true} and +\item \tcode{is_convertible_v} +is \tcode{false}. +\end{itemize} + \pnum \effects Equivalent to: \begin{codeblock} -{ - basic_string_view sv = t; - return assign(sv); -} +basic_string_view sv = t; +return assign(sv); \end{codeblock} - -\pnum -\remarks This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% @@ -1586,14 +1437,8 @@ \begin{itemdescr} \pnum -\returns -\tcode{*this = basic_string(s)}. - -\pnum -\remarks -Uses -\indexlibrary{\idxcode{length}!\idxcode{char_traits}}% -\tcode{traits::length()}. +\effects Equivalent to: +\tcode{return *this = basic_string_view(s);} \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% @@ -1603,8 +1448,10 @@ \begin{itemdescr} \pnum -\returns -\tcode{*this = basic_string(1, c)}. +\effects Equivalent to: +\begin{codeblock} +return *this = basic_string_view(addressof(c), 1); +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator=}{basic_string}% @@ -1614,10 +1461,10 @@ \begin{itemdescr} \pnum -\effects As if by: \tcode{*this = basic_string(il);} - -\pnum -\returns \tcode{*this}. +\effects Equivalent to: +\begin{codeblock} +return *this = basic_string_view(il.begin(), il.size()); +\end{codeblock} \end{itemdescr} \rSec3[string.iterators]{Iterator support} @@ -1683,8 +1530,10 @@ \rSec3[string.capacity]{Capacity} \indexlibrarymember{size}{basic_string}% +\indexlibrarymember{length}{basic_string}% \begin{itemdecl} size_type size() const noexcept; +size_type length() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -1696,17 +1545,6 @@ \complexity Constant time. \end{itemdescr} -\indexlibrarymember{length}{basic_string}% -\begin{itemdecl} -size_type length() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{size()}. -\end{itemdescr} - \indexlibrarymember{max_size}{basic_string}% \begin{itemdecl} size_type max_size() const noexcept; @@ -1728,15 +1566,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{length_error} -if -\tcode{n > max_size()}. - \pnum \effects -Alters the length of the string designated by +Alters the value of \tcode{*this} as follows: @@ -1744,21 +1576,11 @@ \item If \tcode{n <= size()}, -the function replaces the string designated by -\tcode{*this} -with a string of length \tcode{n} whose elements are a -copy of the initial elements of the original string designated by -\tcode{*this}. +erases the last \tcode{size() - n} elements. \item If \tcode{n > size()}, -the function replaces the string designated by -\tcode{*this} -with a string of length \tcode{n} whose first -\tcode{size()} -elements are a copy of the original string designated by -\tcode{*this}, -and whose remaining elements are all initialized to \tcode{c}. +appends \tcode{n - size()} copies of \tcode{c}. \end{itemize} \end{itemdescr} @@ -1770,7 +1592,7 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{resize(n, charT())}. +Equivalent to \tcode{resize(n, charT())}. \end{itemdescr} \indexlibrarymember{capacity}{basic_string}% @@ -1813,10 +1635,8 @@ \throws \tcode{length_error} if -\tcode{res_arg > max_size()}.\footnote{\tcode{reserve()} -uses -\tcode{allocator_traits::allocate()} -which may throw an appropriate exception.} +\tcode{res_arg > max_size()} or any exceptions thrown by +\tcode{allocator_traits} \tcode{::allocate}. \end{itemdescr} \indexlibrarymember{shrink_to_fit}{basic_string}% @@ -1849,11 +1669,7 @@ \begin{itemdescr} \pnum \effects -Behaves as if the function calls: - -\begin{codeblock} -erase(begin(), end()); -\end{codeblock} +Equivalent to: \tcode{erase(begin(), end());} \end{itemdescr} \indexlibrarymember{empty}{basic_string}% @@ -1863,8 +1679,8 @@ \begin{itemdescr} \pnum -\returns -\tcode{size() == 0}. +\effects Equivalent to: +\tcode{return size() == 0;} \end{itemdescr} \rSec3[string.access]{Element access} @@ -1877,7 +1693,7 @@ \begin{itemdescr} \pnum -\requires \tcode{pos <= size()}. +\expects \tcode{pos <= size()}. \pnum \returns \tcode{*(begin() + pos)} if \tcode{pos < size()}. Otherwise, @@ -1918,7 +1734,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{!empty()}. \pnum @@ -1934,7 +1750,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{!empty()}. \pnum @@ -1944,7 +1760,7 @@ \rSec3[string.modifiers]{Modifiers} -\rSec4[string.op+=]{\tcode{basic_string::operator+=}} +\rSec4[string.op.append]{\tcode{basic_string::operator+=}} \indexlibrarymember{operator+=}{basic_string}% \begin{itemdecl} @@ -1953,11 +1769,9 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{append(str)}. +\effects Equivalent to: \tcode{return append(str);} + -\pnum -\returns -\tcode{*this}. \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% @@ -1968,20 +1782,23 @@ \begin{itemdescr} \pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and -then calls \tcode{append(sv)}. - -\pnum -\returns -\tcode{*this}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. +\effects +Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return append(sv); +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% @@ -1991,11 +1808,7 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{append(s)}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return append(s);} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% @@ -2005,11 +1818,7 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{push_back(c)}; - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return append(size_type\{1\}, c);} \end{itemdescr} \indexlibrarymember{operator+=}{basic_string}% @@ -2019,10 +1828,7 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{append(il)}. - -\pnum -\returns \tcode{*this}. +\effects Equivalent to: \tcode{return append(il);} \end{itemdescr} @@ -2035,11 +1841,7 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{append(str.data(), str.size())}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return append(str.data(), str.size());} \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2048,21 +1850,12 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > str.size()}. - \pnum \effects -Determines the effective length \tcode{rlen} -of the string to append as the smaller of \tcode{n} and -\tcode{\tcode{str}.size() - \tcode{pos}} and calls \tcode{append(str.data() + pos, rlen)}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +return append(basic_string_view(str).substr(pos, n)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2072,21 +1865,24 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + \pnum \effects Equivalent to: \begin{codeblock} -{ - basic_string_view sv = t; - return append(sv.data(), sv.size()); -} +basic_string_view sv = t; +return append(sv.data(), sv.size()); \end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2097,27 +1893,23 @@ \begin{itemdescr} \pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > sv.size()}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum \effects -Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t}. -Determines the effective length \tcode{rlen} of the string to append -as the smaller of \tcode{n} and \tcode{sv.size() - pos} -and calls \tcode{append(sv.data() + pos, rlen)}. - -\pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true} and \tcode{is_convertible_v} is \tcode{false}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return append(sv.substr(pos, n)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2127,18 +1919,10 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{n} elements -of \tcode{charT}. - -\pnum -\throws \tcode{length_error} if \tcode{size() + n > max_size()}. +\expects \range{s}{s + n} is a valid range. \pnum -\effects The function replaces the string controlled by \tcode{*this} -with a string of length \tcode{size() + n} whose first \tcode{size()} -elements are a copy of the original string controlled by \tcode{*this} -and whose remaining elements are a copy of the initial \tcode{n} elements -of \tcode{s}. +\effects Appends a copy of the range \range{s}{s + n} to the string. \pnum \returns @@ -2152,15 +1936,7 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\effects Calls \tcode{append(s, traits::length(s))}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return append(s, traits::length(s));} \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2170,7 +1946,10 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{return append(basic_string(n, c));} +\effects Appends \tcode{n} copies of \tcode{c} to the string. + +\pnum +\returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{append}{basic_string}% @@ -2181,7 +1960,9 @@ \begin{itemdescr} \pnum -\requires \range{first}{last} is a valid range. +\constraints +\tcode{InputIterator} is a type that qualifies as an input +iterator\iref{container.requirements.general}. \pnum \effects Equivalent to: \tcode{return append(basic_string(first, last, get_allocator()));} @@ -2194,11 +1975,7 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{append(il.begin(), il.size())}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return append(il.begin(), il.size());} \end{itemdescr} \indexlibrarymember{push_back}{basic_string}% @@ -2210,7 +1987,7 @@ \pnum \effects Equivalent to -\tcode{append(static_cast(1), c)}. +\tcode{append(size_type\{1\}, c)}. \end{itemdescr} \rSec4[string.assign]{\tcode{basic_string::assign}} @@ -2244,22 +2021,12 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > str.size()}. - \pnum \effects -Determines the effective length \tcode{rlen} -of the string to assign as the smaller of \tcode{n} and -\tcode{\tcode{str}.size() - \tcode{pos}} and calls -\tcode{assign(str.data() + pos, rlen)}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +return assign(basic_string_view(str).substr(pos, n)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% @@ -2269,21 +2036,24 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + \pnum \effects Equivalent to: \begin{codeblock} -{ - basic_string_view sv = t; - return assign(sv.data(), sv.size()); -} +basic_string_view sv = t; +return assign(sv.data(), sv.size()); \end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrarymember{assign}{basic_string}% @@ -2294,27 +2064,22 @@ \begin{itemdescr} \pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > sv.size()}. - -\pnum -\effects -Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t}. -Determines the effective length \tcode{rlen} of the string to assign -as the smaller of \tcode{n} and \tcode{sv.size() - pos} -and calls \tcode{assign(sv.data() + pos, rlen)}. - -\pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true} and \tcode{is_convertible_v} is \tcode{false}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum -\returns -\tcode{*this}. +\effects Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return assign(sv.substr(pos, n)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% @@ -2324,14 +2089,12 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{n} elements of \tcode{charT}. - -\pnum -\throws \tcode{length_error} if \tcode{n > max_size()}. +\expects \range{s}{s + n} is a valid range. \pnum -\effects Replaces the string controlled by \tcode{*this} with a string -of length \tcode{n} whose elements are a copy of those pointed to by \tcode{s}. +\effects +Replaces the string controlled by \tcode{*this} with +a copy of the range \range{s}{s + n}. \pnum \returns @@ -2345,15 +2108,7 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\effects Calls \tcode{assign(s, traits::length(s))}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return assign(s, traits::length(s));} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% @@ -2363,14 +2118,9 @@ \begin{itemdescr} \pnum -\effects Calls \tcode{assign(il.begin(), il.size())}. - -\pnum -\returns -\tcode{*this}. +\effects Equivalent to: \tcode{return assign(il.begin(), il.size());} \end{itemdescr} - \indexlibrarymember{assign}{basic_string}% \begin{itemdecl} basic_string& assign(size_type n, charT c); @@ -2378,7 +2128,12 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{return assign(basic_string(n, c));} +\effects Equivalent to: +\begin{codeblock} +clear(); +resize(n, c); +return *this; +\end{codeblock} \end{itemdescr} \indexlibrarymember{assign}{basic_string}% @@ -2388,6 +2143,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{InputIterator} is a type that qualifies as an input +iterator\iref{container.requirements.general}. + \pnum \effects Equivalent to: \tcode{return assign(basic_string(first, last, get_allocator()));} \end{itemdescr} @@ -2410,23 +2170,12 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos1 > size()} -or -\tcode{pos2 > str.size()}. - \pnum \effects -Determines the effective length \tcode{rlen} of the string to insert as the smaller -of \tcode{n} and -\tcode{str.size() - pos2} and calls \tcode{insert(pos1, str.data() + pos2, rlen)}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +return insert(pos1, basic_string_view(str), pos2, n); +\end{codeblock} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% @@ -2436,21 +2185,24 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + \pnum \effects Equivalent to: \begin{codeblock} -{ - basic_string_view sv = t; - return insert(pos, sv.data(), sv.size()); -} +basic_string_view sv = t; +return insert(pos, sv.data(), sv.size()); \end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% @@ -2461,29 +2213,22 @@ \begin{itemdescr} \pnum -\throws -\tcode{out_of_range} -if -\tcode{pos1 > size()} -or -\tcode{pos2 > sv.size()}. - -\pnum -\effects -Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t}. -Determines the effective length \tcode{rlen} of the string to assign -as the smaller of \tcode{n} and \tcode{sv.size() - pos2} -and calls \tcode{insert(pos1, sv.data() + pos2, rlen)}. - -\pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true} and \tcode{is_convertible_v} is \tcode{false}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum -\returns -\tcode{*this}. +\effects Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return insert(pos1, sv.substr(pos2, n)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{insert}{basic_string}% @@ -2493,20 +2238,20 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{n} -elements of \tcode{charT}. +\expects \range{s}{s + n} is a valid range. \pnum -\throws \tcode{out_of_range} if \tcode{pos > size()} or \tcode{length_error} -if \tcode{size() + n > max_size()}. +\throws +\begin{itemize} +\item \tcode{out_of_range} if \tcode{pos > size()}, +\item \tcode{length_error} if \tcode{n > max_size() - size()}, or +\item any exceptions thrown by \tcode{allocator_traits::allocate}. +\end{itemize} \pnum -\effects Replaces the string controlled by \tcode{*this} with a string of -length \tcode{size() + n} whose first \tcode{pos} elements are a copy of -the initial elements of the original string controlled by \tcode{*this} and -whose next \tcode{n} elements are a copy of the elements in \tcode{s} and -whose remaining elements are a copy of the remaining elements of the original -string controlled by \tcode{*this}. +\effects Inserts a copy of the range \range{s}{s + n} +immediately before the character at position \tcode{pos} if \tcode{pos < size()}, +or otherwise at the end of the string. \pnum \returns @@ -2519,10 +2264,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least -\tcode{traits::length(s) + 1} elements of \tcode{charT}. - \pnum \effects Equivalent to: \tcode{return insert(pos, s, traits::length(s));} \end{itemdescr} @@ -2534,7 +2275,17 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{return insert(pos, basic_string(n, c));} +\throws +\begin{itemize} +\item \tcode{out_of_range} if \tcode{pos > size()}, +\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}% @@ -2544,17 +2295,17 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects -Inserts a copy of \tcode{c} before the character referred to by \tcode{p}. +Inserts a copy of \tcode{c} at the position \tcode{p}. \pnum \returns -An iterator which refers to the copy of the inserted character. +An iterator which refers to the inserted character. \end{itemdescr} \indexlibrarymember{insert}{basic_string}% @@ -2564,16 +2315,16 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{p} is a valid iterator on \tcode{*this}. \pnum \effects -Inserts \tcode{n} copies of \tcode{c} before the character referred to by \tcode{p}. +Inserts \tcode{n} copies of \tcode{c} at the position \tcode{p}. \pnum -\returns An iterator which refers to the copy of the first inserted character, or +\returns An iterator which refers to the first inserted character, or \tcode{p} if \tcode{n == 0}. \end{itemdescr} @@ -2585,11 +2336,14 @@ \begin{itemdescr} \pnum -\requires +\constraints +\tcode{InputIterator} is a type that qualifies as an input +iterator\iref{container.requirements.general}. + +\pnum +\expects \tcode{p} is a valid iterator on \tcode{*this}. -\tcode{[first, last)} -is a valid range. \pnum \effects @@ -2597,7 +2351,7 @@ \tcode{insert(p - begin(), basic_string(first, last, get_allocator()))}. \pnum -\returns An iterator which refers to the copy of the first inserted character, or +\returns An iterator which refers to the first inserted character, or \tcode{p} if \tcode{first == last}. \end{itemdescr} @@ -2608,11 +2362,7 @@ \begin{itemdescr} \pnum -\effects As if by \tcode{insert(p, il.begin(), il.end())}. - -\pnum -\returns An iterator which refers to the copy of the first inserted character, or -\tcode{p} if \tcode{i1} is empty. +\effects Equivalent to: \tcode{return insert(p, il.begin(), il.end());} \end{itemdescr} \rSec4[string.erase]{\tcode{basic_string::erase}} @@ -2634,18 +2384,7 @@ Determines the effective length \tcode{xlen} of the string to be removed as the smaller of \tcode{n} and \tcode{size() - pos}. - -\pnum -The function then replaces the string controlled by -\tcode{*this} -with a string of length -\tcode{size() - xlen} -whose first \tcode{pos} elements are a copy of the initial elements of the original string controlled by -\tcode{*this}, -and whose remaining elements are a copy of the elements of the original string controlled by -\tcode{*this} -beginning at position -\tcode{pos + xlen}. +Removes the characters in the range \range{begin() + pos}{begin() + pos + xlen}. \pnum \returns @@ -2658,6 +2397,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{p} is a valid dereferenceable iterator on \tcode{*this}. + \pnum \throws Nothing. @@ -2681,11 +2424,9 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{first} and \tcode{last} are valid iterators on -\tcode{*this}, -defining a range -\tcode{[first, last)}. +\tcode{*this}. \range{first}{last} is a valid range. \pnum \throws Nothing. @@ -2711,7 +2452,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{!empty()}. \pnum @@ -2719,7 +2460,7 @@ \pnum \effects -Equivalent to \tcode{erase(size() - 1, 1)}. +Equivalent to \tcode{erase(end() - 1)}. \end{itemdescr} \rSec4[string.replace]{\tcode{basic_string::replace}} @@ -2741,23 +2482,12 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos1 > size()} -or -\tcode{pos2 > str.size()}. - \pnum \effects -Determines the effective length \tcode{rlen} of the string to be inserted -as the smaller of \tcode{n2} and \tcode{str.size() - pos2} and calls -\tcode{replace(pos1, n1, str.data() + pos2, rlen)}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +return replace(pos1, n1, basic_string_view(str).substr(pos2, n2)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2767,21 +2497,24 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + \pnum \effects Equivalent to: \begin{codeblock} -{ - basic_string_view sv = t; - return replace(pos1, n1, sv.data(), sv.size()); -} +basic_string_view sv = t; +return replace(pos1, n1, sv.data(), sv.size()); \end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2793,29 +2526,23 @@ \begin{itemdescr} \pnum -\throws -\tcode{out_of_range} -if -\tcode{pos1 > size()} -or -\tcode{pos2 > sv.size()}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum \effects -Creates a variable, \tcode{sv}, as if by \tcode{basic_string_view sv = t}. -Determines the effective length \tcode{rlen} of the string to be inserted -as the smaller of \tcode{n2} and \tcode{sv.size() - pos2} -and calls \tcode{replace(pos1, n1, sv.data() + pos2, rlen)}. - -\pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true} and \tcode{is_convertible_v} is \tcode{false}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return replace(pos1, n1, sv.substr(pos2, n2)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2825,24 +2552,24 @@ \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at -least \tcode{n2} elements of \tcode{charT}. +\expects \range{s}{s + n2} is a valid range. \pnum -\throws \tcode{out_of_range} if \tcode{pos1 > size()} or \tcode{length_error} -if the length of the resulting string would exceed \tcode{max_size()} (see below). +\throws +\begin{itemize} +\item \tcode{out_of_range} if \tcode{pos1 > size()}, +\item \tcode{length_error} if the length of the resulting string +would exceed \tcode{max_size()} (see below), or +\item any exceptions thrown by \tcode{allocator_traits::allocate}. +\end{itemize} \pnum \effects Determines the effective length \tcode{xlen} of the string to be removed as the smaller of \tcode{n1} and \tcode{size() - pos1}. If \tcode{size() - xlen >= max_size() - n2} throws \tcode{length_error}. Otherwise, -the function replaces the string controlled by *\tcode{this} with a string of -length \tcode{size() - xlen + n2} whose first \tcode{pos1} elements are a copy -of the initial elements of the original string controlled by \tcode{*this}, -whose next \tcode{n2} elements are a copy of the initial \tcode{n2} elements -of \tcode{s}, and whose remaining elements are a copy of the elements of the -original string controlled by \tcode{*this} beginning at position -\tcode{pos + xlen}. +the function replaces the characters in the range +\range{begin() + pos1}{begin() + pos1 + xlen} +with a copy of the range \range{s}{s + n2}. \pnum \returns @@ -2855,10 +2582,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least -\tcode{traits::length(s) + 1} elements of \tcode{charT}. - \pnum \effects Equivalent to: \tcode{return replace(pos, n, s, traits::length(s));} \end{itemdescr} @@ -2870,7 +2593,24 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{return replace(pos1, n1, basic_string(n2, c));} +\throws +\begin{itemize} +\item \tcode{out_of_range} if \tcode{pos1 > size()}, +\item \tcode{length_error} if the length of the resulting string +would exceed \tcode{max_size()} (see below), or +\item any exceptions thrown by \tcode{allocator_traits::allocate.} +\end{itemize} + +\pnum +\effects Determines the effective length \tcode{xlen} of the string to be +removed as the smaller of \tcode{n1} and \tcode{size() - pos1}. If +\tcode{size() - xlen >=} \tcode{max_size() - n2} throws \tcode{length_error}. Otherwise, +the function replaces the characters in the range +\range{begin() + pos1}{begin() + pos1 + xlen} +with \tcode{n2} copies of \tcode{c}. + +\pnum +\returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2879,17 +2619,9 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires -\range{begin()}{i1} and \range{i1}{i2} are valid ranges. - \pnum \effects -Calls \tcode{replace(i1 - begin(), i2 - i1, str)}. - -\pnum -\returns -\tcode{*this}. +Equivalent to: \tcode{return replace(i1, i2, basic_string_view(str));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2900,24 +2632,27 @@ \begin{itemdescr} \pnum -\requires -\range{begin()}{i1} and \range{i1}{i2} are valid ranges. - -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -calls \tcode{replace(i1 - begin(), i2 - i1, sv)}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} \pnum -\returns -\tcode{*this}. +\expects +\range{begin()}{i1} and \range{i1}{i2} are valid ranges. \pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. +\effects +Equivalent to: +\begin{codeblock} +basic_string_view sv = t; +return replace(i1 - begin(), i2 - i1, sv.data(), sv.size()); +\end{codeblock} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2927,15 +2662,8 @@ \begin{itemdescr} \pnum -\requires \range{begin()}{i1} and \range{i1}{i2} are valid ranges and -\tcode{s} points to an array of at least \tcode{n} elements of \tcode{charT}. - -\pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, s, n)}. - -\pnum -\returns -\tcode{*this}. +\effects +Equivalent to: \tcode{return replace(i1, i2, basic_string_view(s, n));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2945,16 +2673,8 @@ \begin{itemdescr} \pnum -\requires \range{begin()}{i1} and \range{i1}{i2} are valid ranges and -\tcode{s} points to an array of at least \tcode{traits::\brk{}length(s) + 1} -elements of \tcode{charT}. - -\pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, s, traits::length(s))}. - -\pnum -\returns -\tcode{*this}. +\effects +Equivalent to: \tcode{return replace(i1, i2, basic_string_view(s));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2964,14 +2684,11 @@ \begin{itemdescr} \pnum -\requires \range{begin()}{i1} and \range{i1}{i2} are valid ranges. - -\pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, basic_string(n, c))}. +\expects \range{begin()}{i1} and \range{i1}{i2} are valid ranges. \pnum -\returns -\tcode{*this}. +\effects +Equivalent to: \tcode{return replace(i1 - begin(), i2 - i1, n, c);} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2982,14 +2699,13 @@ \begin{itemdescr} \pnum -\requires \range{begin()}{i1}, \range{i1}{i2} and \range{j1}{j2} are valid ranges. - -\pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, basic_string(j1, j2, get_allocator()))}. +\constraints +\tcode{InputIterator} is a type that qualifies as an input +iterator\iref{container.requirements.general}. \pnum -\returns -\tcode{*this}. +\effects +Equivalent to: \tcode{return replace(i1, i2, basic_string(j1, j2, get_allocator()));} \end{itemdescr} \indexlibrarymember{replace}{basic_string}% @@ -2999,17 +2715,10 @@ \begin{itemdescr} \pnum -\requires \range{begin()}{i1} and \range{i1}{i2} are valid ranges. - -\pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, il.begin(), il.size())}. - -\pnum -\returns -\tcode{*this}. +\effects +Equivalent to: \tcode{return replace(i1, i2, il.begin(), il.size());} \end{itemdescr} - \rSec4[string.copy]{\tcode{basic_string::copy}} \indexlibrarymember{copy}{basic_string}% @@ -3018,27 +2727,11 @@ \end{itemdecl} \begin{itemdescr} -\pnum -Let \tcode{rlen} be the smaller of \tcode{n} and \tcode{size() - pos}. - -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > size()}. - -\pnum -\requires -\range{s}{s + rlen} is a valid range. - \pnum \effects -Equivalent to \tcode{traits::copy(s, data() + pos, rlen)}. +Equivalent to: +\tcode{return basic_string_view(*this).copy(s, n, pos);} \begin{note} This does not terminate \tcode{s} with a null object. \end{note} - -\pnum -\returns -\tcode{rlen}. \end{itemdescr} \rSec4[string.swap]{\tcode{basic_string::swap}} @@ -3052,7 +2745,13 @@ \begin{itemdescr} \pnum -\postconditions +\expects +\tcode{allocator_traits::propagate_on_container_swap::value} is \tcode{true} +or +\tcode{get_allocator() == s.get_allocator()}. + +\pnum +\ensures \tcode{*this} contains the same sequence of characters that was in \tcode{s}, \tcode{s} contains the same sequence of characters that was in @@ -3078,15 +2777,15 @@ \begin{itemdescr} \pnum -\returns A pointer \tcode{p} such that \tcode{p + i == \&operator[](i)} for each +\returns A pointer \tcode{p} such that \tcode{p + i == addressof(operator[](i))} for each \tcode{i} in \crange{0}{size()}. \pnum \complexity Constant time. \pnum -\requires -The program shall not alter any of the values stored in the character array. +\remarks +The program shall not modify any of the values stored in the character array; otherwise, the behavior is undefined. \end{itemdescr} \indexlibrarymember{data}{basic_string}% @@ -3096,15 +2795,16 @@ \begin{itemdescr} \pnum -\returns A pointer \tcode{p} such that \tcode{p + i == \&operator[](i)} for each +\returns A pointer \tcode{p} such that \tcode{p + i == addressof(operator[](i))} for each \tcode{i} in \crange{0}{size()}. \pnum \complexity Constant time. \pnum -\requires -The program shall not alter the value stored at \tcode{p + size()}. +\remarks +The program shall not modify the value stored at \tcode{p + size()} +to any value other than \tcode{charT()}; otherwise, the behavior is undefined. \end{itemdescr} \indexlibrarymember{operator basic_string_view}{basic_string}% @@ -3132,752 +2832,282 @@ copy of the most recent replacement. \end{itemdescr} -\rSec4[string.find]{\tcode{basic_string::find}} +\rSec4[string.find]{Searching} + +\pnum +Let \placeholder{F} be one of +\tcode{find}, \tcode{rfind}, \tcode{find_first_of}, \tcode{find_last_of}, +\tcode{find_first_not_of}, and \tcode{find_last_not_of}. + +\begin{itemize} +\item +Each member function of the form +\begin{codeblock} +size_type @\placeholder{F}@(const basic_string& str, size_type pos) const noexcept; +\end{codeblock} +has effects equivalent to: +\tcode{return \placeholder{F}(basic_string_view(str), pos);} + +\item +Each member function of the form +\begin{codeblock} +size_type @\placeholder{F}@(const charT* s, size_type pos) const; +\end{codeblock} +has effects equivalent to: +\tcode{return \placeholder{F}(basic_string_view(s), pos);} + +\item +Each member function of the form +\begin{codeblock} +size_type @\placeholder{F}@(const charT* s, size_type pos, size_type n) const; +\end{codeblock} +has effects equivalent to: +\tcode{return \placeholder{F}(basic_string_view(s, n), pos);} + +\item +Each member function of the form +\begin{codeblock} +size_type @\placeholder{F}@(charT c, size_type pos) const noexcept; +\end{codeblock} +has effects equivalent to: +\begin{codeblock} +return @\placeholder{F}@(basic_string_view(addressof(c), 1), pos); +\end{codeblock} +\end{itemize} \indexlibrarymember{find}{basic_string}% +\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{find_first_of}{basic_string}% +\indexlibrarymember{find_last_of}{basic_string}% +\indexlibrarymember{find_first_not_of}{basic_string}% +\indexlibrarymember{find_last_not_of}{basic_string}% \begin{itemdecl} template - size_type find(const T& t, size_type pos = 0) const; + size_type find(const T& t, size_type pos = 0) const noexcept(@\seebelow@); +template + size_type rfind(const T& t, size_type pos = npos) const noexcept(@\seebelow@); +template + size_type find_first_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); +template + size_type find_last_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); +template + size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(@\seebelow@); +template + size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the lowest position \tcode{xpos}, if possible, such that both of -the following conditions hold: +\constraints \begin{itemize} \item -\tcode{pos <= xpos} and -\tcode{xpos + sv.size() <= size()}; +\tcode{is_convertible_v>} is +\tcode{true} and \item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos + I), sv.at(I))} -for all elements \tcode{I} of the data referenced by \tcode{sv}. +\tcode{is_convertible_v} is +\tcode{false}. \end{itemize} \pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. +\effects +Let \placeholder{G} be the name of the function. +Equivalent to: +\begin{codeblock} +basic_string_view s = *this, sv = t; +return s.@\placeholder{G}@(sv, pos); +\end{codeblock} \pnum \remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. +The expression inside \tcode{noexcept} is equivalent to +\tcode{is_nothrow_convertible_v>}. \end{itemdescr} -\indexlibrarymember{find}{basic_string}% +\rSec4[string.substr]{\tcode{basic_string::substr}} + +\indexlibrarymember{substr}{basic_string}% \begin{itemdecl} -size_type find(const basic_string& str, size_type pos = 0) const noexcept; +basic_string substr(size_type pos = 0, size_type n = npos) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{return find(basic_string_view(str), pos);} -\end{itemdescr} +\throws +\tcode{out_of_range} +if +\tcode{pos > size()}. -\indexlibrarymember{find}{basic_string}% -\begin{itemdecl} -size_type find(const charT* s, size_type pos, size_type n) const; -\end{itemdecl} +\pnum +\effects +Determines the effective length \tcode{rlen} of the string to copy as the smaller of \tcode{n} and +\tcode{size() - pos}. -\begin{itemdescr} \pnum \returns -\tcode{find(basic_string_view(s, n), pos)}. +\tcode{basic_string(data()+pos, rlen)}. \end{itemdescr} -\indexlibrarymember{find}{basic_string}% +\rSec4[string.compare]{\tcode{basic_string::compare}} + +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type find(const charT* s, size_type pos = 0) const; +template + int compare(const T& t) const noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} + +\pnum +\effects +Equivalent to: \tcode{return basic_string_view(*this).compare(t);} \pnum -\returns -\tcode{find(basic_string_view(s), pos)}. +\remarks +The expression inside \tcode{noexcept} is equivalent to +\tcode{is_nothrow_convertible_v>}. \end{itemdescr} -\indexlibrarymember{find}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type find(charT c, size_type pos = 0) const; +template + int compare(size_type pos1, size_type n1, const T& t) const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{find(basic_string(1, c), pos)}. -\end{itemdescr} +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v>} is +\tcode{true} and +\item +\tcode{is_convertible_v} is +\tcode{false}. +\end{itemize} -\rSec4[string.rfind]{\tcode{basic_string::rfind}} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return basic_string_view(*this).substr(pos1, n1).compare(t); +\end{codeblock} +\end{itemdescr} -\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} template - size_type rfind(const T& t, size_type pos = npos) const; + int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the highest position \tcode{xpos}, if possible, such that both of -the following conditions hold: +\constraints \begin{itemize} \item -\tcode{xpos <= pos} -and -\tcode{xpos + sv.size() <= size()}; +\tcode{is_convertible_v>} is +\tcode{true} and \item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos + I), sv.at(I))} -for all elements \tcode{I} of the data referenced by \tcode{sv}. +\tcode{is_convertible_v} is +\tcode{false}. \end{itemize} \pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. +\effects +Equivalent to: +\begin{codeblock} +basic_string_view s = *this, sv = t; +return s.substr(pos1, n1).compare(sv.substr(pos2, n2)); +\end{codeblock} +\end{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. +\indexlibrarymember{compare}{basic_string}% +\begin{itemdecl} +int compare(const basic_string& str) const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. +\effects +Equivalent to: +\tcode{return compare(basic_string_view(str));} \end{itemdescr} -\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; +int compare(size_type pos1, size_type n1, const basic_string& str) const; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return rfind(basic_string_view(str), pos);} +Equivalent to: +\tcode{return compare(pos1, n1, basic_string_view(str));} \end{itemdescr} -\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type rfind(const charT* s, size_type pos, size_type n) const; +int compare(size_type pos1, size_type n1, const basic_string& str, + size_type pos2, size_type n2 = npos) const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rfind(basic_string_view(s, n), pos)}. +\effects Equivalent to: +\begin{codeblock} +return compare(pos1, n1, basic_string_view(str), pos2, n2); +\end{codeblock} \end{itemdescr} -\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type rfind(const charT* s, size_type pos = npos) const; +int compare(const charT* s) const; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. +\effects Equivalent to: +\tcode{return compare(basic_string_view(s));} +\end{itemdescr} + +\indexlibrarymember{compare}{basic_string}% +\begin{itemdecl} +int compare(size_type pos, size_type n1, const charT* s) const; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns -\tcode{rfind(basic_string_view(s), pos)}. +\effects +Equivalent to: \tcode{return compare(pos, n1, basic_string_view(s));} \end{itemdescr} -\indexlibrarymember{rfind}{basic_string}% +\indexlibrarymember{compare}{basic_string}% \begin{itemdecl} -size_type rfind(charT c, size_type pos = npos) const; +int compare(size_type pos, size_type n1, const charT* s, size_type n2) const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rfind(basic_string(1, c), pos)}. +\effects +Equivalent to: \tcode{return compare(pos, n1, basic_string_view(s, n2));} \end{itemdescr} -\rSec4[string.find.first.of]{\tcode{basic_string::find_first_of}} +\rSec4[string.starts.with]{\tcode{basic_string::starts_with}} -\indexlibrarymember{find_first_of}{basic_string}% +\indexlibrarymember{starts_with}{basic_string}% \begin{itemdecl} -template - size_type find_first_of(const T& t, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the lowest position \tcode{xpos}, if possible, such that both of -the following conditions hold: - -\begin{itemize} -\item -\tcode{pos <= xpos} -and -\tcode{xpos < size()}; -\item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos), sv.at(I))} -for some element \tcode{I} of the data referenced by \tcode{sv}. -\end{itemize} - -\pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. -\end{itemdescr} - -\indexlibrarymember{find_first_of}{basic_string}% -\begin{itemdecl} -size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return find_first_of(basic_string_view(str), pos);} -\end{itemdescr} - -\indexlibrarymember{find_first_of}{basic_string}% -\begin{itemdecl} -size_type find_first_of(const charT* s, size_type pos, size_type n) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_first_of(basic_string_view(s, n), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_first_of}{basic_string}% -\begin{itemdecl} -size_type find_first_of(const charT* s, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{find_first_of(basic_string_view(s), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_first_of}{basic_string}% -\begin{itemdecl} -size_type find_first_of(charT c, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_first_of(basic_string(1, c), pos)}. -\end{itemdescr} - -\rSec4[string.find.last.of]{\tcode{basic_string::find_last_of}} - -\indexlibrarymember{find_last_of}{basic_string}% -\begin{itemdecl} -template - size_type find_last_of(const T& t, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the highest position \tcode{xpos}, if possible, such that both of -the following conditions hold: -\begin{itemize} -\item -\tcode{xpos <= pos} -and -\tcode{xpos < size()}; -\item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos), sv.at(I))} -for some element \tcode{I} of the data referenced by \tcode{sv}. -\end{itemize} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. - -\pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. -\end{itemdescr} - -\indexlibrarymember{find_last_of}{basic_string}% -\begin{itemdecl} -size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return find_last_of(basic_string_view(str), pos);} -\end{itemdescr} - -\indexlibrarymember{find_last_of}{basic_string}% -\begin{itemdecl} -size_type find_last_of(const charT* s, size_type pos, size_type n) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_last_of(basic_string_view(s, n), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_last_of}{basic_string}% -\begin{itemdecl} -size_type find_last_of(const charT* s, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{find_last_of(basic_string_view(s), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_last_of}{basic_string}% -\begin{itemdecl} -size_type find_last_of(charT c, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_last_of(basic_string(1, c), pos)}. -\end{itemdescr} - -\rSec4[string.find.first.not.of]{\tcode{basic_string::find_first_not_of}} - -\indexlibrarymember{find_first_not_of}{basic_string}% -\begin{itemdecl} -template - size_type find_first_not_of(const T& t, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the lowest position \tcode{xpos}, if possible, such that both of -the following conditions hold: -\begin{itemize} -\item -\tcode{pos <= xpos} -and -\tcode{xpos < size()}; -\item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos), sv.at(I))} -for no element \tcode{I} of the data referenced by \tcode{sv}. -\end{itemize} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. - -\pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. -\end{itemdescr} - -\indexlibrarymember{find_first_not_of}{basic_string}% -\begin{itemdecl} -size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return find_first_not_of(basic_string_view(str), pos); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{find_first_not_of}{basic_string}% -\begin{itemdecl} -size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_first_not_of(basic_string_view(s, n), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_first_not_of}{basic_string}% -\begin{itemdecl} -size_type find_first_not_of(const charT* s, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{find_first_not_of(basic_string_view(s), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_first_not_of}{basic_string}% -\begin{itemdecl} -size_type find_first_not_of(charT c, size_type pos = 0) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_first_not_of(basic_string(1, c), pos)}. -\end{itemdescr} - -\rSec4[string.find.last.not.of]{\tcode{basic_string::find_last_not_of}} - -\indexlibrarymember{find_last_not_of}{basic_string}% -\begin{itemdecl} -template - size_type find_last_not_of(const T& t, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the highest position \tcode{xpos}, if possible, such that both of -the following conditions hold: -\begin{itemize} -\item -\tcode{xpos <= pos} -and -\tcode{xpos < size()}; -\item -\indexlibrary{\idxcode{eq}!\idxcode{char_traits}}% -\tcode{traits::eq(at(xpos), sv.at(I))} -for no element \tcode{I} of the data referenced by \tcode{sv}. -\end{itemize} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. - -\pnum -\returns -\tcode{xpos} if the function can determine such a value for \tcode{xpos}. -Otherwise, returns -\tcode{npos}. -\end{itemdescr} - -\indexlibrarymember{find_last_not_of}{basic_string}% -\begin{itemdecl} -size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return find_last_not_of(basic_string_view(str), pos); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{find_last_not_of}{basic_string}% -\begin{itemdecl} -size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_last_not_of(basic_string_view(s, n), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_last_not_of}{basic_string}% -\begin{itemdecl} -size_type find_last_not_of(const charT* s, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{s} points to an array of at least \tcode{traits::length(s) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{find_last_not_of(basic_string_view(s), pos)}. -\end{itemdescr} - -\indexlibrarymember{find_last_not_of}{basic_string}% -\begin{itemdecl} -size_type find_last_not_of(charT c, size_type pos = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{find_last_not_of(basic_string(1, c), pos)}. -\end{itemdescr} - -\rSec4[string.substr]{\tcode{basic_string::substr}} - -\indexlibrarymember{substr}{basic_string}% -\begin{itemdecl} -basic_string substr(size_type pos = 0, size_type n = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > size()}. - -\pnum -\effects -Determines the effective length \tcode{rlen} of the string to copy as the smaller of \tcode{n} and -\tcode{size() - pos}. - -\pnum -\returns -\tcode{basic_string(data()+pos, rlen)}. -\end{itemdescr} - -\rSec4[string.compare]{\tcode{basic_string::compare}} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -template - int compare(const T& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Creates a variable, \tcode{sv}, as if by -\tcode{basic_string_view sv = t;} and then -determines the effective length -\tcode{rlen} -of the strings to compare as the smaller of -\tcode{size()} -and -\tcode{sv.size()}. -The function then compares the two strings by calling -\tcode{traits::compare(data(), sv.data(), rlen)}. - -\pnum -\returns -The nonzero result if the result of the comparison is nonzero. -Otherwise, returns a value as indicated in \tref{strings.compare}. - -\begin{floattable}{\tcode{compare()} results}{tab:strings.compare} -{lc} -\topline -\lhdr{Condition} & \rhdr{Return Value} \\ \capsep -\tcode{size() < \ sv.size()} & \tcode{< 0} \\ -\tcode{size() == sv.size()} & \tcode{ \ 0} \\ -\tcode{size() > \ sv.size()} & \tcode{> 0} \\ -\end{floattable} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. - -\pnum -\throws -Nothing unless the initialization of \tcode{sv} throws an exception. -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -template - int compare(size_type pos1, size_type n1, const T& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -{ - basic_string_view sv = t; - return basic_string_view(data(), size()).substr(pos1, n1).compare(sv); -} -\end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution unless -\tcode{is_convertible_v>} is \tcode{true} and -\tcode{is_convertible_v} is \tcode{false}. -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -template - int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -basic_string_view sv = t; -return basic_string_view( - data(), size()).substr(pos1, n1).compare(sv.substr(pos2, n2)); -\end{codeblock} - -\pnum -\remarks -This function shall not participate in overload resolution -unless \tcode{is_convertible_v>} -is \tcode{true} and \tcode{is_convertible_v} is \tcode{false}. -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(const basic_string& str) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\tcode{return compare(basic_string_view(str));} -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(size_type pos1, size_type n1, const basic_string& str) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\tcode{return compare(pos1, n1, basic_string_view(str));} -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(size_type pos1, size_type n1, const basic_string& str, - size_type pos2, size_type n2 = npos) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return compare(pos1, n1, basic_string_view(str), pos2, n2); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(const charT* s) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{compare(basic_string(s))}. -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(size_type pos, size_type n1, const charT* s) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{basic_string(*this, pos, n1).compare(basic_string(s))}. -\end{itemdescr} - -\indexlibrarymember{compare}{basic_string}% -\begin{itemdecl} -int compare(size_type pos, size_type n1, const charT* s, size_type n2) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{basic_string(*this, pos, n1).compare(basic_string(s, n2))}. -\end{itemdescr} - -\rSec4[string.starts.with]{\tcode{basic_string::starts_with}} - -\indexlibrarymember{starts_with}{basic_string}% -\begin{itemdecl} -bool starts_with(basic_string_view x) const noexcept; -bool starts_with(charT x) const noexcept; -bool starts_with(const charT* x) const; +bool starts_with(basic_string_view x) const noexcept; +bool starts_with(charT x) const noexcept; +bool starts_with(const charT* x) const; \end{itemdecl} \begin{itemdescr} @@ -3900,442 +3130,252 @@ \begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -return basic_string_view(data(), size()).ends_with(x); -\end{codeblock} -\end{itemdescr} - -\rSec2[string.nonmembers]{Non-member functions} - -\indexlibrary{\idxcode{basic_string}} - -\rSec3[string.op+]{\tcode{operator+}} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const basic_string& lhs, - const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{basic_string(lhs).append(rhs)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(basic_string&& lhs, - const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(lhs.append(rhs))}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const basic_string& lhs, - basic_string&& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(rhs.insert(0, lhs))}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(basic_string&& lhs, - basic_string&& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(lhs.append(rhs))}. -\begin{note} -Or equivalently, \tcode{std::move(rhs.insert(0, lhs))}. -\end{note} -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const charT* lhs, const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{basic_string(lhs) + rhs}. - -\pnum -\remarks -Uses -\tcode{traits::length()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const charT* lhs, basic_string&& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(rhs.insert(0, lhs))}. - -\pnum -\remarks -Uses -\tcode{traits::length()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(charT lhs, const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{basic_string(1, lhs) + rhs}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(charT lhs, basic_string&& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(rhs.insert(0, 1, lhs))}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const basic_string& lhs, const charT* rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{lhs + basic_string(rhs)}. - -\pnum -\remarks -Uses -\tcode{traits::length()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(basic_string&& lhs, const charT* rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(lhs.append(rhs))}. - -\pnum -\remarks -Uses -\tcode{traits::length()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(const basic_string& lhs, charT rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{lhs + basic_string(1, rhs)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{basic_string}% -\begin{itemdecl} -template - basic_string - operator+(basic_string&& lhs, charT rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{std::move(lhs.append(1, rhs))}. -\end{itemdescr} - -\rSec3[string.operator==]{\tcode{operator==}} - -\indexlibrarymember{operator==}{basic_string}% -\begin{itemdecl} -template - bool operator==(const basic_string& lhs, - const basic_string& rhs) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{lhs.compare(rhs) == 0}. -\end{itemdescr} - -\indexlibrarymember{operator==}{basic_string}% -\begin{itemdecl} -template - bool operator==(const charT* lhs, const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rhs == lhs}. -\end{itemdescr} - -\indexlibrarymember{operator==}{basic_string}% -\begin{itemdecl} -template - bool operator==(const basic_string& lhs, const charT* rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{rhs} points to an array of at least \tcode{traits::length(rhs) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{lhs.compare(rhs) == 0}. -\end{itemdescr} - -\rSec3[string.op!=]{\tcode{operator!=}} - -\indexlibrarymember{operator"!=}{basic_string}% -\begin{itemdecl} -template - bool operator!=(const basic_string& lhs, - const basic_string& rhs) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{!(lhs == rhs)}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{basic_string}% -\begin{itemdecl} -template - bool operator!=(const charT* lhs, const basic_string& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rhs != lhs}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{basic_string}% -\begin{itemdecl} -template - bool operator!=(const basic_string& lhs, const charT* rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{rhs} points to an array of at least \tcode{traits::length(rhs) + 1} -elements of \tcode{charT}. - -\pnum -\returns -\tcode{lhs.compare(rhs) != 0}. +\effects +Equivalent to: +\begin{codeblock} +return basic_string_view(data(), size()).ends_with(x); +\end{codeblock} \end{itemdescr} -\rSec3[string.op<]{\tcode{operator<}} +\rSec2[string.nonmembers]{Non-member functions} + +\indexlibrary{\idxcode{basic_string}} + +\rSec3[string.op.plus]{\tcode{operator+}} -\indexlibrarymember{operator<}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<(const basic_string& lhs, - const basic_string& rhs) noexcept; + basic_string + operator+(const basic_string& lhs, + const basic_string& rhs); +template + basic_string + operator+(const basic_string& lhs, const charT* rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) < 0}. +\effects +Equivalent to: +\begin{codeblock} +basic_string r = lhs; +r.append(rhs); +return r; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator<}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<(const charT* lhs, const basic_string& rhs); + basic_string + operator+(basic_string&& lhs, + const basic_string& rhs); +template + basic_string + operator+(basic_string&& lhs, const charT* rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rhs.compare(lhs) > 0}. +\effects +Equivalent to: +\begin{codeblock} +lhs.append(rhs); +return std::move(lhs); +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator<}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<(const basic_string& lhs, const charT* rhs); + basic_string + operator+(basic_string&& lhs, + basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) < 0}. +\effects +Equivalent to: +\begin{codeblock} +lhs.append(rhs); +return std::move(lhs); +\end{codeblock} +except that both \tcode{lhs} and \tcode{rhs} +are left in valid but unspecified states. +\begin{note} +If \tcode{lhs} and \tcode{rhs} have equal allocators, +the implementation may move from either. +\end{note} \end{itemdescr} -\rSec3[string.op>]{\tcode{operator>}} - -\indexlibrarymember{operator>}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator>(const basic_string& lhs, - const basic_string& rhs) noexcept; + basic_string + operator+(const basic_string& lhs, + basic_string&& rhs); +template + basic_string + operator+(const charT* lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) > 0}. +\effects +Equivalent to: +\begin{codeblock} +rhs.insert(0, lhs); +return std::move(rhs); +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator>}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator>(const charT* lhs, const basic_string& rhs); + basic_string + operator+(const charT* lhs, const basic_string& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rhs.compare(lhs) < 0}. +\effects +Equivalent to: +\begin{codeblock} +basic_string r = rhs; +r.insert(0, lhs); +return r; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator>}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator>(const basic_string& lhs, const charT* rhs); + basic_string + operator+(charT lhs, const basic_string& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) > 0}. +\effects +Equivalent to: +\begin{codeblock} +basic_string r = rhs; +r.insert(r.begin(), lhs); +return r; +\end{codeblock} \end{itemdescr} -\rSec3[string.op<=]{\tcode{operator<=}} - -\indexlibrarymember{operator<=}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<=(const basic_string& lhs, - const basic_string& rhs) noexcept; + basic_string + operator+(charT lhs, basic_string&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) <= 0}. +\effects +Equivalent to: +\begin{codeblock} +rhs.insert(rhs.begin(), lhs); +return std::move(rhs); +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator<=}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<=(const charT* lhs, const basic_string& rhs); + basic_string + operator+(const basic_string& lhs, charT rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rhs.compare(lhs) >= 0}. +\effects +Equivalent to: +\begin{codeblock} +basic_string r = lhs; +r.push_back(rhs); +return r; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{operator<=}{basic_string}% +\indexlibrarymember{operator+}{basic_string}% \begin{itemdecl} template - bool operator<=(const basic_string& lhs, const charT* rhs); + basic_string + operator+(basic_string&& lhs, charT rhs); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) <= 0}. +\effects +Equivalent to: +\begin{codeblock} +lhs.push_back(rhs); +return std::move(lhs); +\end{codeblock} \end{itemdescr} -\rSec3[string.op>=]{\tcode{operator>=}} - -\indexlibrarymember{operator>=}{basic_string}% +\rSec3[string.cmp]{Non-member comparison functions} \begin{itemdecl} template - bool operator>=(const basic_string& lhs, + bool operator==(const basic_string& lhs, const basic_string& rhs) noexcept; -\end{itemdecl} +template + bool operator==(const charT* lhs, const basic_string& rhs); +template + bool operator==(const basic_string& lhs, const charT* rhs); -\begin{itemdescr} -\pnum -\returns -\tcode{lhs.compare(rhs) >= 0}. -\end{itemdescr} +template + bool operator!=(const basic_string& lhs, + const basic_string& rhs) noexcept; +template + bool operator!=(const charT* lhs, const basic_string& rhs); +template + bool operator!=(const basic_string& lhs, const charT* rhs); -\indexlibrarymember{operator>=}{basic_string}% -\begin{itemdecl} template - bool operator>=(const charT* lhs, const basic_string& rhs); -\end{itemdecl} + bool operator< (const basic_string& lhs, + const basic_string& rhs) noexcept; +template + bool operator< (const charT* lhs, const basic_string& rhs); +template + bool operator< (const basic_string& lhs, const charT* rhs); -\begin{itemdescr} -\pnum -\returns -\tcode{rhs.compare(lhs) <= 0}. -\end{itemdescr} +template + bool operator> (const basic_string& lhs, + const basic_string& rhs) noexcept; +template + bool operator> (const charT* lhs, const basic_string& rhs); +template + bool operator> (const basic_string& lhs, const charT* rhs); -\indexlibrarymember{operator>=}{basic_string}% -\begin{itemdecl} +template + bool operator<=(const basic_string& lhs, + const basic_string& rhs) noexcept; +template + bool operator<=(const charT* lhs, const basic_string& rhs); +template + bool operator<=(const basic_string& lhs, const charT* rhs); + +template + bool operator>=(const basic_string& lhs, + const basic_string& rhs) noexcept; +template + bool operator>=(const charT* lhs, const basic_string& rhs); template bool operator>=(const basic_string& lhs, const charT* rhs); \end{itemdecl} - \begin{itemdescr} \pnum -\returns -\tcode{lhs.compare(rhs) >= 0}. +\effects Let \tcode{\placeholder{op}} be the operator. +Equivalent to: +\begin{codeblock} + return basic_string_view(lhs) @\placeholder{op}@ basic_string_view(rhs); +\end{codeblock} \end{itemdescr} \rSec3[string.special]{\tcode{swap}} @@ -4515,6 +3555,32 @@ \tcode{getline(is, str, is.widen('\textbackslash n'))}. \end{itemdescr} +\rSec3[string.erasure]{Erasure} + +\indexlibrary{\idxcode{erase}!\idxcode{basic_string}}% +\begin{itemdecl} +template + void erase(basic_string& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove(c.begin(), c.end(), value), c.end());} +\end{itemdescr} + +\indexlibrary{\idxcode{erase_if}!\idxcode{basic_string}}% +\begin{itemdecl} +template + void erase_if(basic_string& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{c.erase(remove_if(c.begin(), c.end(), pred), c.end());} +\end{itemdescr} + \rSec2[string.conversions]{Numeric conversions} \indexlibrary{\idxcode{stoi}}% @@ -4718,10 +3784,12 @@ \indexlibrary{\idxcode{hash}!\idxcode{pmr::wstring}}% \begin{itemdecl} template<> struct hash; +template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; +template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; @@ -4748,6 +3816,16 @@ \tcode{string\{str, len\}}. \end{itemdescr} +\indexlibrarymember{operator""""s}{u8string}% +\begin{itemdecl} +u8string operator""s(const char8_t* str, size_t len); +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\tcode{u8string\{str, len\}}. +\end{itemdescr} + \indexlibrarymember{operator""""s}{u16string}% \begin{itemdecl} u16string operator""s(const char16_t* str, size_t len); @@ -4832,6 +3910,7 @@ // \tcode{basic_string_view} typedef names using string_view = basic_string_view; + using u8string_view = basic_string_view; using u16string_view = basic_string_view; using u32string_view = basic_string_view; using wstring_view = basic_string_view; @@ -4839,6 +3918,7 @@ // \ref{string.view.hash}, hash support template struct hash; template<> struct hash; + template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; @@ -4847,6 +3927,7 @@ inline namespace string_view_literals { // \ref{string.view.literals}, suffix for \tcode{basic_string_view} literals constexpr string_view operator""sv(const char* str, size_t len) noexcept; + constexpr u8string_view operator""sv(const char8_t* str, size_t len) noexcept; constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept; constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept; @@ -4910,6 +3991,9 @@ constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; + friend constexpr const_iterator begin(basic_string_view sv) noexcept { return sv.begin(); } + friend constexpr const_iterator end(basic_string_view sv) noexcept { return sv.end(); } + // \ref{string.view.capacity}, capacity constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; @@ -4929,7 +4013,7 @@ constexpr void swap(basic_string_view& s) noexcept; // \ref{string.view.ops}, string operations - size_type copy(charT* s, size_type n, size_type pos = 0) const; + constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; @@ -4985,8 +4069,10 @@ \end{codeblock} \pnum -In every specialization \tcode{basic_string_view}, the type \tcode{traits} shall satisfy the character traits requirements\iref{char.traits}, -and the type \tcode{traits::char_type} shall name the same type as \tcode{charT}. +In every specialization \tcode{basic_string_view}, the type \tcode{traits} shall satisfy the character traits requirements\iref{char.traits}. +\begin{note} +The program is ill-formed if \tcode{traits::char_type} is not the same type as \tcode{charT}. +\end{note} \pnum The type \tcode{iterator} satisfies @@ -5009,7 +4095,7 @@ Constructs an empty \tcode{basic_string_view}. \pnum -\postconditions +\ensures \tcode{size_ == 0} and \tcode{data_ == nullptr}. \end{itemdescr} @@ -5020,17 +4106,13 @@ \begin{itemdescr} \pnum -\requires +\expects \range{str}{str + traits::length(str)} is a valid range. \pnum \effects -Constructs a \tcode{basic_string_view}, with the postconditions -in \tref{string.view.ctr.2}. -\begin{libefftabvaluenarrow}{\tcode{basic_string_view(const charT*)} effects}{tab:string.view.ctr.2} -\tcode{data_} & \tcode{str} \\ -\tcode{size_} & \tcode{traits::length(str)} \\ -\end{libefftabvaluenarrow} +Constructs a \tcode{basic_string_view}, initializing \tcode{data_} with \tcode{str} +and initializing \tcode{size_} with \tcode{traits::length(str)}. \pnum \complexity @@ -5044,16 +4126,13 @@ \begin{itemdescr} \pnum -\requires +\expects \range{str}{str + len} is a valid range. \pnum \effects -Constructs a \tcode{basic_string_view}, with the postconditions in \tref{string.view.ctr.3}. -\begin{libefftabvaluenarrow}{\tcode{basic_string_view(const charT*, size_type)} effects}{tab:string.view.ctr.3} -\tcode{data_} & \tcode{str} \\ -\tcode{size_} & \tcode{len} \\ -\end{libefftabvaluenarrow} +Constructs a \tcode{basic_string_view}, initializing \tcode{data_} with \tcode{str} +and initializing \tcode{size_} with \tcode{len}. \end{itemdescr} \rSec3[string.view.iterators]{Iterator support} @@ -5066,8 +4145,9 @@ \begin{itemdescr} \pnum A type that meets the requirements -of a constant random access iterator\iref{random.access.iterators} and -of a contiguous iterator\iref{iterator.requirements.general} +of a constant +\oldconcept{RandomAccessIterator}\iref{random.access.iterators} and +models \libconcept{ContiguousIterator}\iref{iterator.concept.contiguous}, whose \tcode{value_type} is the template parameter \tcode{charT}. \pnum @@ -5089,7 +4169,7 @@ \returns An iterator such that \begin{itemize} -\item if \tcode{!empty()}, \tcode{\&*begin() == data_}, +\item if \tcode{!empty()}, \tcode{addressof(*begin()) == data_}, \item otherwise, an unspecified value such that \range{begin()}{end()} is a valid range. \end{itemize} \end{itemdescr} @@ -5136,18 +4216,9 @@ \rSec3[string.view.capacity]{Capacity} \indexlibrarymember{size}{basic_string_view}% -\begin{itemdecl} -constexpr size_type size() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{size_}. -\end{itemdescr} - \indexlibrarymember{length}{basic_string_view}% \begin{itemdecl} +constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; \end{itemdecl} @@ -5157,6 +4228,7 @@ \tcode{size_}. \end{itemdescr} + \indexlibrarymember{max_size}{basic_string_view}% \begin{itemdecl} constexpr size_type max_size() const noexcept; @@ -5188,7 +4260,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{pos < size()}. \pnum @@ -5228,7 +4300,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{!empty()}. \pnum @@ -5247,7 +4319,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{!empty()}. \pnum @@ -5286,7 +4358,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{n <= size()}. \pnum @@ -5301,7 +4373,7 @@ \begin{itemdescr} \pnum -\requires +\expects \tcode{n <= size()}. \pnum @@ -5324,7 +4396,7 @@ \indexlibrarymember{copy}{basic_string_view}% \begin{itemdecl} -size_type copy(charT* s, size_type n, size_type pos = 0) const; +constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; \end{itemdecl} \begin{itemdescr} @@ -5336,7 +4408,7 @@ \tcode{out_of_range} if \tcode{pos > size()}. \pnum -\requires +\expects \range{s}{s + rlen} is a valid range. \pnum @@ -5478,7 +4550,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return starts_with(basic_string_view(\&x, 1));} +Equivalent to: \tcode{return starts_with(basic_string_view(addressof(x), 1));} \end{itemdescr} \indexlibrarymember{starts_with}{basic_string_view}% @@ -5514,7 +4586,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return ends_with(basic_string_view(\&x, 1));} +Equivalent to: \tcode{return ends_with(basic_string_view(addressof(x), 1));} \end{itemdescr} \indexlibrarymember{ends_with}{basic_string_view}% @@ -5530,34 +4602,41 @@ \rSec3[string.view.find]{Searching} -\pnum -This subclause specifies the \tcode{basic_string_view} member functions named -\tcode{find}, \tcode{rfind}, \tcode{find_first_of}, \tcode{find_last_of}, \tcode{find_first_not_of}, and \tcode{find_last_not_of}. - \pnum Member functions in this subclause have complexity \bigoh{\tcode{size() * str.size()}} at worst, although implementations should do better. \pnum +Let \placeholder{F} be one of +\tcode{find}, +\tcode{rfind}, +\tcode{find_first_of}, +\tcode{find_last_of}, +\tcode{find_first_not_of}, +and +\tcode{find_last_not_of}. +\begin{itemize} +\item Each member function of the form \begin{codeblock} -constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos); +constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos) const; \end{codeblock} -is equivalent to \tcode{return \placeholder{F}(basic_string_view(s), pos);} +has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s), pos);} -\pnum +\item Each member function of the form \begin{codeblock} -constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos, size_type n); +constexpr @\placeholder{return-type}@ @\placeholder{F}@(const charT* s, size_type pos, size_type n) const; \end{codeblock} -is equivalent to \tcode{return \placeholder{F}(basic_string_view(s, n), pos);} +has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(s, n), pos);} -\pnum +\item Each member function of the form \begin{codeblock} -constexpr @\placeholder{return-type}@ @\placeholder{F}@(charT c, size_type pos); +constexpr @\placeholder{return-type}@ @\placeholder{F}@(charT c, size_type pos) const noexcept; \end{codeblock} -is equivalent to \tcode{return \placeholder{F}(basic_string_view(\&c, 1), pos);} +has effects equivalent to: \tcode{return \placeholder{F}(basic_string_view(addressof(c), 1), pos);} +\end{itemize} \indexlibrarymember{find}{basic_string_view}% \begin{itemdecl} @@ -5743,7 +4822,6 @@ \begin{example} A sample conforming implementation for \tcode{operator==} would be: \begin{codeblock} -template using __identity = decay_t; template constexpr bool operator==(basic_string_view lhs, basic_string_view rhs) noexcept { @@ -5751,11 +4829,11 @@ } template constexpr bool operator==(basic_string_view lhs, - __identity> rhs) noexcept { + type_identity_t> rhs) noexcept { return lhs.compare(rhs) == 0; } template - constexpr bool operator==(__identity> lhs, + constexpr bool operator==(type_identity_t> lhs, basic_string_view rhs) noexcept { return lhs.compare(rhs) == 0; } @@ -5870,11 +4948,13 @@ \rSec2[string.view.hash]{Hash support} \indexlibrary{\idxcode{hash}!\idxcode{string_view}}% +\indexlibrary{\idxcode{hash}!\idxcode{u8string_view}}% \indexlibrary{\idxcode{hash}!\idxcode{u16string_view}}% \indexlibrary{\idxcode{hash}!\idxcode{u32string_view}}% \indexlibrary{\idxcode{hash}!\idxcode{wstring_view}}% \begin{itemdecl} template<> struct hash; +template<> struct hash; template<> struct hash; template<> struct hash; template<> struct hash; @@ -5902,6 +4982,16 @@ \tcode{string_view\{str, len\}}. \end{itemdescr} +\indexlibrarymember{operator""""sv}{u8string_view}% +\begin{itemdecl} +constexpr u8string_view operator""sv(const char8_t* str, size_t len) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\tcode{u8string_view\{str, len\}}. +\end{itemdescr} + \indexlibrarymember{operator""""sv}{u16string_view}% \begin{itemdecl} constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; @@ -6298,6 +5388,8 @@ \indexhdr{cuchar}% \indexlibrary{\idxcode{mbstate_t}}% \indexlibrary{\idxcode{size_t}}% +\indexlibrary{\idxcode{mbrtoc8}}% +\indexlibrary{\idxcode{c8rtomb}}% \indexlibrary{\idxcode{mbrtoc16}}% \indexlibrary{\idxcode{c16rtomb}}% \indexlibrary{\idxcode{mbrtoc32}}% @@ -6307,6 +5399,8 @@ using mbstate_t = @\seebelow@; using size_t = @\textit{see \ref{support.types.layout}}@; + size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); + size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps); size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps); size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps); @@ -6318,8 +5412,9 @@ \indexhdr{uchar.h}% The contents and meaning of the header \tcode{} are the same as the C standard library header -\tcode{}, except that it does not declare types \tcode{char16_t} nor -\tcode{char32_t}. +\tcode{}, except that it +declares the additional \tcode{mbrtoc8} and \tcode{c8rtomb} functions +and does not declare types \tcode{char16_t} nor \tcode{char32_t}. \xrefc{7.28} @@ -6329,7 +5424,8 @@ \indexhdr{cstdlib}% \indexhdr{cwchar}% \begin{note} -The headers \tcode{}\iref{cstdlib.syn} +The headers \tcode{}\iref{cstdlib.syn}, +\tcode{}\iref{cuchar.syn}, and \tcode{}\iref{cwchar.syn} declare the functions described in this subclause. \end{note} @@ -6402,3 +5498,92 @@ \end{itemdescr} \xrefc{7.29.6.3} + +\indexlibrary{\idxcode{mbrtoc8}}% +\begin{itemdecl} +size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{s} is a null pointer, +equivalent to \tcode{mbrtoc8(nullptr, "", 1, ps)}. +Otherwise, the function inspects at most \tcode{n} bytes +beginning with the byte pointed to by \tcode{s} +to determine the number of bytes needed to complete +the next multibyte character (including any shift sequences). +If the function determines +that the next multibyte character is complete and valid, +it determines the values of the corresponding UTF-8 code units and then, +if \tcode{pc8} is not a null pointer, +stores the value of the first (or only) such code unit +in the object pointed to by \tcode{pc8}. +Subsequent calls will store successive UTF-8 code units +without consuming any additional input +until all the code units have been stored. +If the corresponding Unicode character is U+0000, +the resulting state described is the initial conversion state. + +\pnum +\returns +The first of the following that applies (given the current conversion state): +\begin{itemize} +\item \tcode{0}, if the next \tcode{n} or fewer bytes complete +the multibyte character +that corresponds to the U+0000 Unicode character +(which is the value stored). +\item between \tcode{1} and \tcode{n} inclusive, +if the next n or fewer bytes complete a valid multibyte character +(which is the value stored); +the value returned is the number of bytes that complete the multibyte character. +\item \tcode{(size_t)(-3)}, if the next character +resulting from a previous call has been stored +(no bytes from the input have been consumed by this call). +\item \tcode{(size_t)(-2)}, if the next \tcode{n} bytes +contribute to an incomplete (but potentially valid) multibyte character, and +all \tcode{n} bytes have been processed (no value is stored). +\item \tcode{(size_t)(-1)}, if an encoding error occurs, +in which case the next \tcode{n} or fewer bytes do not contribute to +a complete and valid multibyte character (no value is stored); +the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, and +the conversion state is unspecified. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{c8rtomb}}% +\begin{itemdecl} +size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{s} is a null pointer, equivalent to +\tcode{c8rtomb(buf, u8'$\backslash$0', ps)} +where \tcode{buf} is an internal buffer. +Otherwise, if \tcode{c8} completes a sequence of valid UTF-8 code units, +determines the number of bytes needed +to represent the multibyte character (including any shift sequences), +and stores the multibyte character representation in the array +whose first element is pointed to by \tcode{s}. +At most \tcode{MB_CUR_MAX} bytes are stored. +If the multibyte character is a null character, a null byte is stored, +preceded by any shift sequence needed to restore the initial shift state; +the resulting state described is the initial conversion state. + +\pnum +\returns +The number of bytes stored in the array object (including any shift sequences). +If \tcode{c8} does not contribute to a sequence of \tcode{char8_t} +corresponding to a valid multibyte character, +the value of the macro \tcode{EILSEQ} is stored in \tcode{errno}, +\tcode{(size_t) (-1)} is returned, and the conversion state is unspecified. + +\pnum +\remarks +Calls to \tcode{c8rtomb} with a null pointer argument for \tcode{s} +may introduce a data race\iref{res.on.data.races} +with other calls to \tcode{c8rtomb} +with a null pointer argument for \tcode{s}. +\end{itemdescr} diff --git a/source/styles.tex b/source/styles.tex index 9614ac53c0..1bff754958 100644 --- a/source/styles.tex +++ b/source/styles.tex @@ -156,13 +156,13 @@ %% (copied verbatim from listings.sty version 1.6 except where commented) \makeatletter -\lst@CheckVersion{1.6}{\lst@CheckVersion{1.5b}{ +\lst@CheckVersion{1.7}{\lst@CheckVersion{1.6}{\lst@CheckVersion{1.5b}{ \typeout{^^J% ***^^J% *** This file requires listings.sty version 1.6.^^J% *** You have version \lst@version; exiting ...^^J% ***^^J}% - \batchmode \@@end}} + \batchmode \@@end}}} \def\lst@Init#1{% \begingroup diff --git a/source/support.tex b/source/support.tex index 1563b0a794..00f6e5aa08 100644 --- a/source/support.tex +++ b/source/support.tex @@ -555,24 +555,41 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_bit_cast} & \tcode{201806L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_bind_front} & \tcode{201811L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_bool_constant} & \tcode{201505L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_boyer_moore_searcher} & \tcode{201603L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_byte} & \tcode{201603L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_char8_t} & \tcode{201811L} & + \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \tcode{} + \\ \rowsep \defnlibxname{cpp_lib_chrono} & \tcode{201611L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_chrono_udls} & \tcode{201304L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_clamp} & \tcode{201603L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_complex_udls} & \tcode{201309L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_concepts} & \tcode{201806L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_constexpr_misc} & \tcode{201811L} & + \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_constexpr_swap_algorithms} & \tcode{201806L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_destroying_delete} & \tcode{201806L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_enable_shared_from_this} & \tcode{201603L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_erase_if} & \tcode{201811L} & + \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_exchange_function} & \tcode{201304L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_execution} & \tcode{201603L} & @@ -583,6 +600,8 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_generic_associative_lookup} & \tcode{201304L} & \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_generic_unordered_lookup} & \tcode{201811L} & + \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_hardware_interference_size} & \tcode{201703L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_has_unique_object_representations} & \tcode{201606L} & @@ -599,6 +618,8 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_is_aggregate} & \tcode{201703L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_constant_evaluated} & \tcode{201811L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_is_final} & \tcode{201402L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_is_invocable} & \tcode{201703L} & @@ -642,6 +663,9 @@ \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_quoted_string_io} & \tcode{201304L} & \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_ranges} & \tcode{201811L} & + \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \\ \rowsep \defnlibxname{cpp_lib_raw_memory_algorithms} & \tcode{201606L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_result_of_sfinae} & \tcode{201210L} & @@ -664,8 +688,10 @@ \tcode{} \\ \rowsep \defnlibxname{cpp_lib_string_view} & \tcode{201606L} & \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_three_way_comparison} & \tcode{201711L} & + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_to_chars} & \tcode{201611L} & - \tcode{} \\ \rowsep + \tcode{} \\ \rowsep \defnlibxname{cpp_lib_transformation_trait_aliases} & \tcode{201304L} & \tcode{} \\ \rowsep \defnlibxname{cpp_lib_transparent_operators} & \tcode{201510L} & @@ -707,6 +733,7 @@ template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; + template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; @@ -3439,7 +3466,7 @@ object. \pnum -\postconditions If \tcode{*this} and \tcode{rhs} both have dynamic type \tcode{exception} +\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. \end{itemdescr} @@ -3918,7 +3945,7 @@ \effects Constructs an empty \tcode{initializer_list} object. \pnum -\postconditions \tcode{size() == 0}. +\ensures \tcode{size() == 0}. \end{itemdescr} \rSec2[support.initlist.access]{Initializer list access} @@ -4098,7 +4125,7 @@ int value; // \expos // exposition-only constructor - explicit constexpr weak_equality(eq v) noexcept : value(int(v)) {} // \expos + constexpr explicit weak_equality(eq v) noexcept : value(int(v)) {} // \expos public: // valid values @@ -4175,7 +4202,7 @@ int value; // \expos // exposition-only constructor - explicit constexpr strong_equality(eq v) noexcept : value(int(v)) {} // \expos + constexpr explicit strong_equality(eq v) noexcept : value(int(v)) {} // \expos public: // valid values @@ -4273,11 +4300,11 @@ bool is_ordered; // \expos // exposition-only constructors - explicit constexpr + constexpr explicit partial_ordering(eq v) noexcept : value(int(v)), is_ordered(true) {} // \expos - explicit constexpr + constexpr explicit partial_ordering(ord v) noexcept : value(int(v)), is_ordered(true) {} // \expos - explicit constexpr + constexpr explicit partial_ordering(ncmp v) noexcept : value(int(v)), is_ordered(false) {} // \expos public: @@ -4419,8 +4446,8 @@ int value; // \expos // exposition-only constructors - explicit constexpr weak_ordering(eq v) noexcept : value(int(v)) {} // \expos - explicit constexpr weak_ordering(ord v) noexcept : value(int(v)) {} // \expos + constexpr explicit weak_ordering(eq v) noexcept : value(int(v)) {} // \expos + constexpr explicit weak_ordering(ord v) noexcept : value(int(v)) {} // \expos public: // valid values @@ -4565,8 +4592,8 @@ int value; // \expos // exposition-only constructors - explicit constexpr strong_ordering(eq v) noexcept : value(int(v)) {} // \expos - explicit constexpr strong_ordering(ord v) noexcept : value(int(v)) {} // \expos + constexpr explicit strong_ordering(eq v) noexcept : value(int(v)) {} // \expos + constexpr explicit strong_ordering(ord v) noexcept : value(int(v)) {} // \expos public: // valid values diff --git a/source/templates.tex b/source/templates.tex index 51940745a6..a6d04e7b27 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -57,6 +57,12 @@ identifier \end{bnf} +\begin{bnf} +\nontermdef{type-constraint}\br + \opt{nested-name-specifier} concept-name\br + \opt{nested-name-specifier} concept-name \terminal{<} \opt{template-argument-list} \terminal{>} +\end{bnf} + \begin{note} The \tcode{>} token following the \grammarterm{template-parameter-list} of a \grammarterm{template-declaration} @@ -147,6 +153,23 @@ When such a declaration is used to declare a class template, no declarator is permitted. +\pnum +A \grammarterm{type-constraint} \tcode{Q} that designates a concept \tcode{C} +can be used to constrain a +contextually-determined type or template type parameter pack \tcode{T} +with a \grammarterm{constraint-expression} \tcode{E} defined as follows. +If \tcode{Q} is of the form \tcode{C}, +then let \tcode{E$'$} be \tcode{C}. +Otherwise, let \tcode{E$'$} be \tcode{C}. +If \tcode{T} is not a pack, +then \tcode{E} is \tcode{E$'$}, +otherwise \tcode{E} is \tcode{(E$'$ \&\& ...)}. +This \grammarterm{constraint-expression} \tcode{E} is called the +\defnx{immediately-declared constraint}{constraint!immediately-declared} +of \tcode{T}. +The concept designated by a \grammarterm{type-constraint} +shall be a type concept\iref{temp.concept}. + \pnum \indextext{template name!linkage of}% A template name has linkage\iref{basic.link}. @@ -238,14 +261,15 @@ \begin{bnf} \nontermdef{template-parameter}\br type-parameter\br - parameter-declaration\br - constrained-parameter + parameter-declaration \end{bnf} \begin{bnf} \nontermdef{type-parameter}\br type-parameter-key \opt{\terminal{...}} \opt{identifier}\br type-parameter-key \opt{identifier} \terminal{=} type-id\br + type-constraint \opt{\terminal{...}} \opt{identifier}\br + type-constraint \opt{identifier} \terminal{=} type-id\br template-head type-parameter-key \opt{\terminal{...}} \opt{identifier}\br template-head type-parameter-key \opt{identifier} \terminal{=} id-expression \end{bnf} @@ -256,30 +280,6 @@ \terminal{typename} \end{bnf} -\begin{bnf} -\nontermdef{constrained-parameter}\br - qualified-concept-name \terminal{...} \opt{identifier}\br - qualified-concept-name \opt{identifier} \opt{default-template-argument} -\end{bnf} - -\begin{bnf} -\nontermdef{qualified-concept-name}\br - \opt{nested-name-specifier} concept-name\br - \opt{nested-name-specifier} partial-concept-id -\end{bnf} - -\begin{bnf} -\nontermdef{partial-concept-id}\br - concept-name \terminal{<} \opt{template-argument-list} \terminal{>} -\end{bnf} - -\begin{bnf} -\nontermdef{default-template-argument}\br - \terminal{=} type-id\br - \terminal{=} id-expression\br - \terminal{=} initializer-clause -\end{bnf} - \begin{note} The \tcode{>} token following the \grammarterm{template-parameter-list} of a \grammarterm{type-parameter} @@ -466,108 +466,28 @@ \end{example} \pnum -A \grammarterm{partial-concept-id} is -a \grammarterm{concept-name} followed by -a sequence of \grammarterm{template-argument}{s}. -These template arguments -are used to form a \grammarterm{constraint-expression} -as described below. - -\pnum -A \grammarterm{constrained-parameter} declares -a template parameter -whose kind (type, non-type, template) and type -match that of the prototype parameter\iref{temp.concept} -of the concept designated by -the \grammarterm{qualified-concept-name} in -the \grammarterm{constrained-parameter}. -Let \tcode{X} be the prototype parameter of the designated concept. -The declared template parameter is determined by -the kind of \tcode{X} (type, non-type, template) -and the optional ellipsis in the \grammarterm{constrained-parameter} -as follows. - -\begin{itemize} -\item If \tcode{X} is a type \grammarterm{template-parameter}, -the declared parameter is a type \grammarterm{template-parameter}. - -\item If \tcode{X} is a non-type \grammarterm{template-parameter}, -the declared parameter is a non-type \grammarterm{template-parameter} -having the same type as \tcode{X}. - -\item If \tcode{X} is a template \grammarterm{template-parameter}, -the declared parameter is a template \grammarterm{template-parameter} -having the same \grammarterm{template-parameter-list} as \tcode{X}, -excluding default template arguments. - -\item If the \grammarterm{qualified-concept-name} is followed by an ellipsis, -then the declared parameter is a template parameter pack\iref{temp.variadic}. -\end{itemize} - -\begin{example} -\begin{codeblock} -template concept C1 = true; -template class X> concept C2 = true; -template concept C3 = true; -template concept C4 = true; -template concept C5 = true; - -template void f1(); // OK, \tcode{T} is a type \grammarterm{template-parameter} -template void f2(); // OK, \tcode{X} is a template with one \grammarterm{type-parameter} -template void f3(); // OK, \tcode{N} has type \tcode{int} -template void f4(); // OK, \tcode{Ts} is a template parameter pack of types -template void f5(); // OK, \tcode{T} is a type \grammarterm{template-parameter} -template void f6(); // OK, \tcode{Cs} is a template parameter pack of \tcode{char}s -\end{codeblock} -\end{example} - -\pnum -A \grammarterm{constrained-parameter} introduces -a \grammarterm{constraint-expression}\iref{temp.constr.decl}. -The expression is derived from -the \grammarterm{qualified-concept-name} \tcode{Q} in -the \grammarterm{constrained-parameter}, -its designated concept \tcode{C}, and -the declared template parameter \tcode{P}. - -\begin{itemize} -\item First, a template argument \tcode{A} is formed from \tcode{P}. -If \tcode{P} declares a template parameter pack\iref{temp.variadic} -and \tcode{C} is a variadic concept\iref{temp.concept}, -then \tcode{A} is the pack expansion \tcode{P...}. -Otherwise, -\tcode{A} is the \grammarterm{id-expression} \tcode{P}. - -% FIXME: This does not guarantee that the expression has the same -% namespace qualification as Q. -\item Then, an \grammarterm{id-expression} \tcode{E} is formed as follows. -If \tcode{Q} is a \grammarterm{concept-name}, -then \tcode{E} is \tcode{C}. -Otherwise, -\tcode{Q} is a \grammarterm{partial-concept-id} -of the form \tcode{C}, -and \tcode{E} is \tcode{C}. - -\item Finally, if \tcode{P} declares a template parameter pack -and \tcode{C} is not a variadic concept, -\tcode{E} is adjusted to be the \grammarterm{fold-expression} -\tcode{(E \&\& ...)}\iref{expr.prim.fold}. -\end{itemize} - -\tcode{E} is the introduced \grammarterm{constraint-expression}. +A \grammarterm{type-parameter} that starts with a \grammarterm{type-constraint} +introduces the immediately-declared constraint\iref{temp} of the parameter. \begin{example} \begin{codeblock} template concept C1 = true; template concept C2 = true; template concept C3 = true; -template struct s1; // associates \tcode{C1} -template struct s2; // associates \tcode{(C1 \&\& ...)} -template struct s3; // associates \tcode{C2} -template T> struct s4; // associates \tcode{C3} +template struct s1; // associates \tcode{C1} +template struct s2; // associates \tcode{(C1 \&\& ...)} +template struct s3; // associates \tcode{(C2 \&\& ...)} +template T> struct s4; // associates \tcode{C3} +template... T> struct s5; // associates \tcode{(C3 \&\& ...)} \end{codeblock} \end{example} +\pnum +A non-type template parameter declared with a type that +contains a placeholder type with a \grammarterm{type-constraint} +introduces the immediately-declared constraint of +the invented type corresponding to the placeholder\iref{dcl.fct}. + \pnum A \defnx{default template-argument}{\idxgram{template-argument}!default} @@ -600,26 +520,6 @@ that declaration shall be a definition and shall be the only declaration of the function template in the translation unit. -\pnum -The default \grammarterm{template-argument} -of a \grammarterm{constrained-parameter} -shall match the kind (type, non-type, template) -of the declared template parameter. -\begin{example} -\begin{codeblock} -template concept C1 = true; -template concept C2 = true; -template class X> concept C3 = true; - -template struct S0; - -template struct S1; // OK -template struct S2; // OK -template struct S3; // OK -template struct S4; // error: default argument is not a type -\end{codeblock} -\end{example} - \pnum The set of default \grammarterm{template-argument}{s} @@ -749,7 +649,10 @@ contains one or more unexpanded packs is a pack expansion. Similarly, a template parameter pack that is a \grammarterm{type-parameter} with a \grammarterm{template-parameter-list} containing one or more unexpanded -packs is a pack expansion. A template parameter pack that is a pack +packs is a pack expansion. +A type parameter pack with a \grammarterm{type-constraint} that +contains an unexpanded parameter pack is a pack expansion. +A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same \grammarterm{template-parameter-list}. \begin{example} @@ -960,14 +863,13 @@ \pnum \indextext{specialization!class template}% -A -\grammarterm{simple-template-id} -that names a class template specialization is a -\grammarterm{class-name}\iref{class}. - -\pnum -A \grammarterm{template-id} that names an alias template -specialization is a \grammarterm{type-name}. +\begin{note} +A \grammarterm{simple-template-id} +that names a class template specialization +is a \grammarterm{class-name}\iref{class.name}. +Any other \grammarterm{simple-template-id} that names a type +is a \grammarterm{typedef-name}. +\end{note} \pnum A \grammarterm{template-id} is \defnx{valid}{\idxgram{template-id}!valid} if @@ -1683,8 +1585,8 @@ called the \defn{parameter mapping}\iref{temp.constr.decl}. \begin{note} Atomic constraints are formed by constraint normalization\iref{temp.constr.normal}. -\tcode{E} is never a logical AND expression\iref{expr.log.and} -nor a logical OR expression\iref{expr.log.or}. +\tcode{E} is never a logical \logop{AND} expression\iref{expr.log.and} +nor a logical \logop{OR} expression\iref{expr.log.or}. \end{note} \pnum @@ -1744,7 +1646,7 @@ \pnum Constraints can also be associated with a declaration through the use of -\grammarterm{constrained-parameter}{s} in a +\grammarterm{type-constraint}{s} in a \grammarterm{template-parameter-list}. Each of these forms introduces additional \grammarterm{constraint-expression}{s} that are used to constrain the declaration. @@ -1762,25 +1664,30 @@ of that expression. \item Otherwise, the associated constraints are the normal form of a logical -AND expression\iref{expr.log.and} whose operands are in the +\logop{AND} expression\iref{expr.log.and} whose operands are in the following order: \begin{itemize} \item -the \grammarterm{constraint-expression} introduced by each -\grammarterm{constrained-parameter}\iref{temp.param} in the -declaration's \grammarterm{template-parameter-list}, in -order of appearance, and +the \grammarterm{constraint-expression} introduced by +each \grammarterm{type-constraint}\iref{temp.param} in +the declaration's \grammarterm{template-parameter-list}, +in order of appearance, and \item -the \grammarterm{constraint-expression} introduced -by a \grammarterm{requires-clause} following a -\grammarterm{template-parameter-list}\iref{temp}, and +the \grammarterm{constraint-expression} introduced by +a \grammarterm{requires-clause} following +a \grammarterm{template-parameter-list}\iref{temp}, and \item -the \grammarterm{constraint-expression} introduced by a trailing -\grammarterm{requires-clause}\iref{dcl.decl} -of a function declaration\iref{dcl.fct}. +the \grammarterm{constraint-expression} introduced by +each \grammarterm{type-constraint} in +the parameter-type-list of a function declaration, and + +\item +the \grammarterm{constraint-expression} introduced by +a trailing \grammarterm{requires-clause}\iref{dcl.decl} of +a function declaration\iref{dcl.fct}. \end{itemize} \end{itemize} @@ -2118,7 +2025,7 @@ \pnum For purposes of name lookup and instantiation, default arguments, -\grammarterm{partial-concept-id}{s}, +\grammarterm{type-constraint}{s}, \grammarterm{requires-clause}{s}\iref{temp}, and \grammarterm{noexcept-specifier}{s} @@ -2128,7 +2035,7 @@ are considered definitions; each default argument, -\grammarterm{partial-concept-id}{s}, +\grammarterm{type-constraint}, \grammarterm{requires-clause}, or \grammarterm{noexcept-specifier} @@ -2137,7 +2044,7 @@ to the templated function definition or to any other default arguments -\grammarterm{partial-concept-id}{s}, +\grammarterm{type-constraint}{s}, \grammarterm{requires-clause}{s}, or \grammarterm{noexcept-specifier}{s}. @@ -2637,12 +2544,14 @@ \item In a template parameter pack that is a pack expansion\iref{temp.param}: \begin{itemize} -\item if the template parameter pack is a \grammarterm{parameter-declaration}; +\item +if the template parameter pack is a \grammarterm{parameter-declaration}; the pattern is the \grammarterm{parameter-declaration} without the ellipsis; -\item if the template parameter pack is a \grammarterm{type-parameter} with a -\grammarterm{template-parameter-list}; the pattern is the corresponding -\grammarterm{type-parameter} without the ellipsis. +\item +if the template parameter pack is a \grammarterm{type-parameter}; +the pattern is the corresponding \grammarterm{type-parameter} +without the ellipsis. \end{itemize} \item In an \grammarterm{initializer-list}\iref{dcl.init}; @@ -3799,7 +3708,8 @@ in the type of the value synthesized for a non-type template parameter is also a unique synthesized type. \end{note} -If only one of the function templates \placeholder{M} is a non-static +If only one of the function templates \placeholder{M} is +a member function, and that function is a non-static member of some class \placeholder{A}, \placeholder{M} is considered to have a new first parameter inserted in its function parameter list. Given \cv{} as the cv-qualifiers of \placeholder{M} @@ -3908,7 +3818,7 @@ template void g(T); // \#4 void h(int i) { - f(&i); // error: ambiguous + f(&i); // OK: calls \#2 g(&i); // OK: calls \#3 } \end{codeblock} @@ -4019,7 +3929,7 @@ requires C // \tcode{C} constrains \tcode{f1(T)} in \grammarterm{constraint-expression} T f1(T x) { return x; } -template // \tcode{C} constrains \tcode{f2(T)} as a \grammarterm{constrained-parameter} +template // \tcode{C}, as a \grammarterm{type-constraint}, constrains \tcode{f2(T)} T f2(T x) { return x; } \end{codeblock} \end{example} @@ -4045,10 +3955,10 @@ \pnum The first declared template parameter of a concept definition is its \defnx{prototype parameter}{prototype parameter!concept}. -\indextext{variadic concept|see{concept, variadic}}% -A \defnx{variadic concept}{concept!variadic} +\indextext{type concept|see{concept, type}}% +A \defnx{type concept}{concept!type} is a concept whose prototype parameter -is a template parameter pack. +is a type \grammarterm{template-parameter}. \rSec1[temp.res]{Name resolution} @@ -4277,7 +4187,7 @@ and the template is not instantiated, or \item no substitution of template arguments -into a \grammarterm{partial-concept-id} or \grammarterm{requires-clause} +into a \grammarterm{type-constraint} or \grammarterm{requires-clause} would result in a valid expression, or \item every valid specialization of a variadic template requires an empty template @@ -5214,8 +5124,6 @@ \begin{ncsimplebnf} literal\br -postfix-expression \terminal{.} pseudo-destructor-name\br -postfix-expression \terminal{->} pseudo-destructor-name\br \terminal{sizeof} unary-expression\br \terminal{sizeof (} type-id \terminal{)}\br \terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br @@ -5755,7 +5663,7 @@ instantiated (this includes their default arguments, \grammarterm{noexcept-specifier}{s}, and non-static data member initializers, if any, -but not their \grammarterm{partial-concept-id}{s} or \grammarterm{requires-clause}{s}). +but not their \grammarterm{type-constraint}{s} or \grammarterm{requires-clause}{s}). As a result, the dependent names are looked up, the semantic constraints are checked, and any templates used are instantiated as part of the instantiation of the entity within which the local class or @@ -6082,7 +5990,7 @@ \end{example} \pnum -The \grammarterm{partial-concept-id}{s} and \grammarterm{requires-clause} +The \grammarterm{type-constraint}{s} and \grammarterm{requires-clause} of a template specialization or member function are not instantiated along with the specialization or function itself, even for a member function of a local class; @@ -6137,6 +6045,7 @@ \pnum \indextext{instantiation!explicit}% +\indextext{\idxcode{extern template}|see{instantiation, explicit}}% A class, function, variable, or member template specialization can be explicitly instantiated from its template. A member function, member class or static data member of a class template can @@ -6147,7 +6056,7 @@ member function of a class template, or variable template shall not -use the \tcode{inline} or \tcode{constexpr} specifiers. +use the \tcode{inline}, \tcode{constexpr}, or \tcode{consteval} specifiers. \pnum The syntax for explicit instantiation is: @@ -6955,7 +6864,7 @@ may be omitted from the list of explicit \grammarterm{template-argument}{s}. A trailing template parameter pack\iref{temp.variadic} not otherwise deduced will be -deduced to an empty sequence of template arguments. +deduced as an empty sequence of template arguments. If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list \tcode{<>} @@ -6971,13 +6880,13 @@ template X f(Y); template X g(Y); void h() { - int i = f(5.6); // \tcode{Y} is deduced to be \tcode{double} + int i = f(5.6); // \tcode{Y} deduced as \tcode{double} int j = f(5.6); // ill-formed: \tcode{X} cannot be deduced - f(f); // \tcode{Y} for outer \tcode{f} deduced to be \tcode{int (*)(bool)} + f(f); // \tcode{Y} for outer \tcode{f} deduced as \tcode{int (*)(bool)} f(f); // ill-formed: \tcode{f} does not denote a single function template specialization - int k = g(5.6); // \tcode{Y} is deduced to be double, \tcode{Z} is deduced to an empty sequence - f(g); // \tcode{Y} for outer \tcode{f} is deduced to be \tcode{int (*)(bool)}, - // \tcode{Z} is deduced to an empty sequence + int k = g(5.6); // \tcode{Y} deduced as double; \tcode{Z} deduced as an empty sequence + f(g); // \tcode{Y} for outer \tcode{f} deduced as \tcode{int (*)(bool)}, + // \tcode{Z} deduced as an empty sequence } \end{codeblock} \end{example} @@ -7014,8 +6923,8 @@ template void f2(); void g() { f("aa",3.0); - f("aa",3.0); // \tcode{Z} is deduced to be \tcode{double} - f("aa",3.0); // \tcode{Y} is deduced to be \tcode{const char*}, and \tcode{Z} is deduced to be \tcode{double} + f("aa",3.0); // \tcode{Z} deduced as \tcode{double} + f("aa",3.0); // \tcode{Y} deduced as \tcode{const char*}; \tcode{Z} deduced as \tcode{double} f("aa",3.0); // error: \tcode{X} cannot be deduced f2(); // OK } @@ -7064,7 +6973,7 @@ template void f(Types ... values); void g() { - f(0, 0, 0); // \tcode{Types} is deduced to the sequence \tcode{int*}, \tcode{float*}, \tcode{int} + f(0, 0, 0); // \tcode{Types} deduced as the sequence \tcode{int*}, \tcode{float*}, \tcode{int} } \end{codeblock} \end{example} @@ -7451,25 +7360,25 @@ \begin{example} \begin{codeblock} template void f(std::initializer_list); -f({1,2,3}); // \tcode{T} deduced to \tcode{int} -f({1,"asdf"}); // error: \tcode{T} deduced to both \tcode{int} and \tcode{const char*} +f({1,2,3}); // \tcode{T} deduced as \tcode{int} +f({1,"asdf"}); // error: \tcode{T} deduced as both \tcode{int} and \tcode{const char*} template void g(T); g({1,2,3}); // error: no argument deduced for \tcode{T} template void h(T const(&)[N]); -h({1,2,3}); // \tcode{T} deduced to \tcode{int}, \tcode{N} deduced to \tcode{3} +h({1,2,3}); // \tcode{T} deduced as \tcode{int}; \tcode{N} deduced as \tcode{3} template void j(T const(&)[3]); -j({42}); // \tcode{T} deduced to \tcode{int}, array bound not considered +j({42}); // \tcode{T} deduced as \tcode{int}; array bound not considered struct Aggr { int i; int j; }; template void k(Aggr const(&)[N]); k({1,2,3}); // error: deduction fails, no conversion from \tcode{int} to \tcode{Aggr} -k({{1},{2},{3}}); // OK, \tcode{N} deduced to \tcode{3} +k({{1},{2},{3}}); // OK, \tcode{N} deduced as \tcode{3} template void m(int const(&)[M][N]); -m({{1,2},{3,4}}); // \tcode{M} and \tcode{N} both deduced to \tcode{2} +m({{1,2},{3,4}}); // \tcode{M} and \tcode{N} both deduced as \tcode{2} template void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, \tcode{T} is \tcode{Aggr}, \tcode{N} is \tcode{3} @@ -7494,8 +7403,8 @@ void h(int x, float& y) { const int z = x; - f(x, y, z); // \tcode{Types} is deduced to \tcode{int}, \tcode{float}, \tcode{const int} - g(x, y, z); // \tcode{T1} is deduced to \tcode{int}; \tcode{Types} is deduced to \tcode{float}, \tcode{int} + f(x, y, z); // \tcode{Types} deduced as \tcode{int}, \tcode{float}, \tcode{const int} + g(x, y, z); // \tcode{T1} deduced as \tcode{int}; \tcode{Types} deduced as \tcode{float}, \tcode{int} g1(x, y, z); // error: \tcode{Types} is not deduced g1(x, y, z); // OK, no deduction occurs } @@ -7883,7 +7792,7 @@ template operator T***(); }; A a; -const int * const * const * p1 = a; // \tcode{T} is deduced as \tcode{int}, not \tcode{const int} +const int * const * const * p1 = a; // \tcode{T} deduced as \tcode{int}, not \tcode{const int} \end{codeblock} \end{example} @@ -8540,7 +8449,7 @@ }; using R = long; -using R = C>::Q; // OK; \tcode{T} was deduced to \tcode{long} from the +using R = C>::Q; // OK; \tcode{T} was deduced as \tcode{long} from the // template argument value in the type \tcode{A<2>} \end{codeblock} \end{example} @@ -8553,7 +8462,7 @@ }; using V = decltype(sizeof 0); -using V = S::Q; // OK; \tcode{T} was deduced to \tcode{std::size_t} from the type \tcode{int[42]} +using V = S::Q; // OK; \tcode{T} was deduced as \tcode{std::size_t} from the type \tcode{int[42]} \end{codeblock} \end{example} @@ -8579,11 +8488,11 @@ void g() { int v[10][20]; - f1(v); // OK: \tcode{i} deduced to be \tcode{20} + f1(v); // OK: \tcode{i} deduced as \tcode{20} f1<20>(v); // OK f2(v); // error: cannot deduce template-argument \tcode{i} f2<10>(v); // OK - f3(v); // OK: \tcode{i} deduced to be \tcode{10} + f3(v); // OK: \tcode{i} deduced as \tcode{10} } \end{codeblock} \end{note} @@ -8625,8 +8534,8 @@ B<77> b; int x = deduce<77>(a.xm, 62, b.ym); -// \tcode{T} is deduced to be \tcode{int}, \tcode{a.xm} must be convertible to \tcode{A::X} -// \tcode{i} is explicitly specified to be \tcode{77}, \tcode{b.ym} must be convertible to \tcode{B<77>::Y} +// \tcode{T} deduced as \tcode{int}; \tcode{a.xm} must be convertible to \tcode{A::X} +// \tcode{i} is explicitly specified to be \tcode{77}; \tcode{b.ym} must be convertible to \tcode{B<77>::Y} \end{codeblock} \end{note} diff --git a/source/threads.tex b/source/threads.tex index f4cf99412c..323ce3fc3b 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -283,7 +283,8 @@ result, where \tcode{decay_copy} is defined as follows: \begin{codeblock} -template decay_t decay_copy(T&& v) +template constexpr decay_t decay_copy(T&& v) + noexcept(is_nothrow_convertible_v>) { return std::forward(v); } \end{codeblock} @@ -414,7 +415,7 @@ \begin{itemdescr} \pnum\effects Constructs an object of type \tcode{id}. -\pnum\postconditions The constructed object does not represent a thread of execution. +\pnum\ensures The constructed object does not represent a thread of execution. \end{itemdescr} \indexlibrarymember{operator==}{thread::id}% @@ -501,7 +502,7 @@ \pnum The specialization is enabled\iref{unord.hash}. \end{itemdescr} -\rSec3[thread.thread.constr]{\tcode{thread} constructors} +\rSec3[thread.thread.constr]{Constructors} \indexlibrary{\idxcode{thread}!constructor}% \begin{itemdecl} @@ -511,7 +512,7 @@ \begin{itemdescr} \pnum\effects Constructs a \tcode{thread} object that does not represent a thread of execution. -\pnum\postconditions \tcode{get_id() == id()}. +\pnum\ensures \tcode{get_id() == id()}. \end{itemdescr} \indexlibrary{\idxcode{thread}!constructor}% @@ -560,7 +561,7 @@ \pnum\sync The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of \tcode{f}. -\pnum\postconditions \tcode{get_id() != id()}. \tcode{*this} represents the newly started thread. +\pnum\ensures \tcode{get_id() != id()}. \tcode{*this} represents the newly started thread. \pnum\throws \tcode{system_error} if unable to start the new thread. @@ -583,12 +584,12 @@ \tcode{x} to a default constructed state. \pnum -\postconditions \tcode{x.get_id() == id()} and \tcode{get_id()} returns the +\ensures \tcode{x.get_id() == id()} and \tcode{get_id()} returns the value of \tcode{x.get_id()} prior to the start of construction. \end{itemdescr} -\rSec3[thread.thread.destr]{\tcode{thread} destructor} +\rSec3[thread.thread.destr]{Destructor} \indexlibrary{\idxcode{thread}!destructor}% \begin{itemdecl} @@ -605,7 +606,7 @@ \end{note} \end{itemdescr} -\rSec3[thread.thread.assign]{\tcode{thread} assignment} +\rSec3[thread.thread.assign]{Assignment} \indexlibrarymember{operator=}{thread}% \begin{itemdecl} @@ -618,14 +619,14 @@ state of \tcode{x} to \tcode{*this} and sets \tcode{x} to a default constructed state. \pnum -\postconditions \tcode{x.get_id() == id()} and \tcode{get_id()} returns the value of +\ensures \tcode{x.get_id() == id()} and \tcode{get_id()} returns the value of \tcode{x.get_id()} prior to the assignment. \pnum \returns \tcode{*this}. \end{itemdescr} -\rSec3[thread.thread.member]{\tcode{thread} members} +\rSec3[thread.thread.member]{Members} \indexlibrarymember{swap}{thread}% \begin{itemdecl} @@ -663,7 +664,7 @@ \tcode{*this} are not synchronized. \end{note} \pnum -\postconditions The thread represented by \tcode{*this} has completed. \tcode{get_id() == id()}. +\ensures The thread represented by \tcode{*this} has completed. \tcode{get_id() == id()}. \pnum \throws \tcode{system_error} when @@ -693,7 +694,7 @@ thread of execution. When the thread previously represented by \tcode{*this} ends execution, the implementation shall release any owned resources. -\pnum\postconditions \tcode{get_id() == id()}. +\pnum\ensures \tcode{get_id() == id()}. \pnum\throws \tcode{system_error} when an exception is required\iref{thread.req.exception}. @@ -717,7 +718,7 @@ \tcode{*this}. \end{itemdescr} -\rSec3[thread.thread.static]{\tcode{thread} static members} +\rSec3[thread.thread.static]{Static members} \indexlibrarymember{hardware_concurrency}{thread}% \begin{itemdecl} @@ -731,7 +732,7 @@ well-defined, an implementation should return 0. \end{itemdescr} -\rSec3[thread.thread.algorithm]{\tcode{thread} specialized algorithms} +\rSec3[thread.thread.algorithm]{Specialized algorithms} \indexlibrarymember{swap}{thread}% \begin{itemdecl} @@ -938,7 +939,7 @@ \effects Blocks the calling thread until ownership of the mutex can be obtained for the calling thread. \pnum -\postconditions The calling thread owns the mutex. +\ensures The calling thread owns the mutex. \pnum \returntype \tcode{void}. @@ -1362,7 +1363,7 @@ If an exception is thrown then a shared lock shall not have been acquired for the current thread. \pnum -\postconditions The calling thread has a shared lock on the mutex. +\ensures The calling thread has a shared lock on the mutex. \pnum \returntype \tcode{void}. @@ -1695,10 +1696,7 @@ the calling thread does not own the mutex \tcode{m}. \pnum -\effects As if by \tcode{m.lock()}. - -\pnum -\postconditions \tcode{\&pm == \&m} +\effects Initializes \tcode{pm} with \tcode{m}. Calls \tcode{m.lock()}. \end{itemdescr} \indexlibrary{\idxcode{lock_guard}!constructor}% @@ -1711,7 +1709,7 @@ \requires The calling thread owns the mutex \tcode{m}. \pnum -\postconditions \tcode{\&pm == \&m} +\effects Initializes \tcode{pm} with \tcode{m}. \pnum \throws Nothing. @@ -1886,7 +1884,7 @@ meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}, \tcode{unique_lock} also meets the \oldconcept{TimedLockable} requirements. \end{note} -\rSec4[thread.lock.unique.cons]{\tcode{unique_lock} constructors, destructor, and assignment} +\rSec4[thread.lock.unique.cons]{Constructors, destructor, and assignment} \indexlibrary{\idxcode{unique_lock}!constructor}% \begin{itemdecl} @@ -1898,7 +1896,7 @@ \effects Constructs an object of type \tcode{unique_lock}. \pnum -\postconditions \tcode{pm == 0} and \tcode{owns == false}. +\ensures \tcode{pm == 0} and \tcode{owns == false}. \end{itemdescr} \indexlibrary{\idxcode{unique_lock}!constructor}% @@ -1914,7 +1912,7 @@ \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.lock()}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == true}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == true}. \end{itemdescr} \indexlibrary{\idxcode{unique_lock}!constructor}% @@ -1927,7 +1925,7 @@ \effects Constructs an object of type \tcode{unique_lock}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == false}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == false}. \end{itemdescr} \indexlibrary{\idxcode{unique_lock}!constructor}% @@ -1946,7 +1944,7 @@ \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.try_lock()}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res}, +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock()}. \end{itemdescr} @@ -1963,7 +1961,7 @@ \effects Constructs an object of type \tcode{unique_lock}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == true}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == true}. \pnum \throws Nothing. @@ -1985,7 +1983,7 @@ \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.try_lock_until(abs_time)}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res}, +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock_until(abs_time)}. \end{itemdescr} @@ -2005,7 +2003,7 @@ \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.try_lock_for(rel_time)}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res}, +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock_for(rel_time)}. \end{itemdescr} @@ -2015,7 +2013,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum\postconditions \tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.pm == 0} and \tcode{u.owns == false}. +\pnum\ensures \tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.pm == 0} and \tcode{u.owns == false}. \end{itemdescr} \indexlibrarymember{operator=}{unique_lock}% @@ -2026,7 +2024,7 @@ \begin{itemdescr} \pnum\effects If \tcode{owns} calls \tcode{pm->unlock()}. -\pnum\postconditions \tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.pm == 0} and \tcode{u.owns == false}. +\pnum\ensures \tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.pm == 0} and \tcode{u.owns == false}. \pnum \begin{note} With a recursive mutex it is possible for both \tcode{*this} and \tcode{u} to own the same mutex before the assignment. In this case, \tcode{*this} will own the mutex after the assignment and \tcode{u} will not. \end{note} @@ -2044,7 +2042,7 @@ \pnum\effects If \tcode{owns} calls \tcode{pm->unlock()}. \end{itemdescr} -\rSec4[thread.lock.unique.locking]{\tcode{unique_lock} locking} +\rSec4[thread.lock.unique.locking]{Locking} \indexlibrarymember{lock}{unique_lock}% \begin{itemdecl} @@ -2056,7 +2054,7 @@ \effects As if by \tcode{pm->lock()}. \pnum -\postconditions \tcode{owns == true}. +\ensures \tcode{owns == true}. \pnum \throws @@ -2088,7 +2086,7 @@ \pnum\returns The value returned by the call to \tcode{try_lock()}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{try_lock()}. \pnum @@ -2123,7 +2121,7 @@ \returns The value returned by the call to \tcode{try_lock_until(abs_time)}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{try_lock_until(abs_time)}. \pnum @@ -2156,7 +2154,7 @@ \returns The value returned by the call to \tcode{try_lock_until(rel_time)}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{try_lock_for(rel_time)}. +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{try_lock_for(rel_time)}. \pnum \throws Any exception thrown by \tcode{pm->try_lock_for()}. \tcode{system_error} when an @@ -2179,7 +2177,7 @@ \begin{itemdescr} \pnum\effects As if by \tcode{pm->unlock()}. -\pnum\postconditions \tcode{owns == false}. +\pnum\ensures \tcode{owns == false}. \pnum\throws \tcode{system_error} when an exception is required\iref{thread.req.exception}. @@ -2190,7 +2188,7 @@ \end{itemize} \end{itemdescr} -\rSec4[thread.lock.unique.mod]{\tcode{unique_lock} modifiers} +\rSec4[thread.lock.unique.mod]{Modifiers} \indexlibrarymember{swap}{unique_lock}% \begin{itemdecl} @@ -2209,7 +2207,7 @@ \begin{itemdescr} \pnum\returns The previous value of \tcode{pm}. -\pnum\postconditions \tcode{pm == 0} and \tcode{owns == false}. +\pnum\ensures \tcode{pm == 0} and \tcode{owns == false}. \end{itemdescr} \indexlibrarymember{swap}{unique_lock}% @@ -2222,7 +2220,7 @@ \pnum\effects As if by \tcode{x.swap(y)}. \end{itemdescr} -\rSec4[thread.lock.unique.obs]{\tcode{unique_lock} observers} +\rSec4[thread.lock.unique.obs]{Observers} \indexlibrarymember{owns_lock}{unique_lock}% \begin{itemdecl} @@ -2323,7 +2321,7 @@ \begin{note} \tcode{shared_lock} meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \end{note} -\rSec4[thread.lock.shared.cons]{\tcode{shared_lock} constructors, destructor, and assignment} +\rSec4[thread.lock.shared.cons]{Constructors, destructor, and assignment} \indexlibrary{\idxcode{shared_lock}!constructor}% \begin{itemdecl} @@ -2335,7 +2333,7 @@ \effects Constructs an object of type \tcode{shared_lock}. \pnum -\postconditions \tcode{pm == nullptr} and \tcode{owns == false}. +\ensures \tcode{pm == nullptr} and \tcode{owns == false}. \end{itemdescr} \indexlibrary{\idxcode{shared_lock}!constructor}% @@ -2351,7 +2349,7 @@ \effects Constructs an object of type \tcode{shared_lock} and calls \tcode{m.lock_shared()}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == true}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == true}. \end{itemdescr} \indexlibrary{\idxcode{shared_lock}!constructor}% @@ -2364,7 +2362,7 @@ \effects Constructs an object of type \tcode{shared_lock}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == false}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == false}. \end{itemdescr} \indexlibrary{\idxcode{shared_lock}!constructor}% @@ -2380,7 +2378,7 @@ \effects Constructs an object of type \tcode{shared_lock} and calls \tcode{m.try_lock_shared()}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res} +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared()}. \end{itemdescr} @@ -2398,7 +2396,7 @@ \effects Constructs an object of type \tcode{shared_lock}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == true}. +\ensures \tcode{pm == addressof(m)} and \tcode{owns == true}. \end{itemdescr} \indexlibrary{\idxcode{shared_lock}!constructor}% @@ -2417,7 +2415,7 @@ \tcode{m.try_lock_shared_until(abs_time)}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res} +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared_until(abs_time)}. \end{itemdescr} @@ -2438,7 +2436,7 @@ \tcode{m.try_lock_shared_for(rel_time)}. \pnum -\postconditions \tcode{pm == addressof(m)} and \tcode{owns == res} +\ensures \tcode{pm == addressof(m)} and \tcode{owns == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared_for(rel_time)}. \end{itemdescr} @@ -2460,7 +2458,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where +\ensures \tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where \tcode{sl_p} is the state of \tcode{sl} just prior to this construction), \tcode{sl.pm == nullptr} and \tcode{sl.owns == false}. \end{itemdescr} @@ -2475,12 +2473,12 @@ \effects If \tcode{owns} calls \tcode{pm->unlock_shared()}. \pnum -\postconditions \tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where +\ensures \tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where \tcode{sl_p} is the state of \tcode{sl} just prior to this assignment), \tcode{sl.pm == nullptr} and \tcode{sl.owns == false}. \end{itemdescr} -\rSec4[thread.lock.shared.locking]{\tcode{shared_lock} locking} +\rSec4[thread.lock.shared.locking]{Locking} \indexlibrarymember{lock}{shared_lock}% \begin{itemdecl} @@ -2492,7 +2490,7 @@ \effects As if by \tcode{pm->lock_shared()}. \pnum -\postconditions \tcode{owns == true}. +\ensures \tcode{owns == true}. \pnum \throws Any exception thrown by \tcode{pm->lock_shared()}. @@ -2520,7 +2518,7 @@ \returns The value returned by the call to \tcode{pm->try_lock_shared()}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared()}. \pnum @@ -2551,7 +2549,7 @@ \tcode{pm->try_lock_shared_until(abs_time)}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared_until(abs_time)}. \pnum @@ -2581,7 +2579,7 @@ \returns The value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}. \pnum -\postconditions \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}. +\ensures \tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}. \pnum \throws Any exception thrown by \tcode{pm->try_lock_shared_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. @@ -2605,7 +2603,7 @@ \effects As if by \tcode{pm->unlock_shared()}. \pnum -\postconditions \tcode{owns == false}. +\ensures \tcode{owns == false}. \pnum \throws \tcode{system_error} when an exception is required\iref{thread.req.exception}. @@ -2618,7 +2616,7 @@ \end{itemize} \end{itemdescr} -\rSec4[thread.lock.shared.mod]{\tcode{shared_lock} modifiers} +\rSec4[thread.lock.shared.mod]{Modifiers} \indexlibrarymember{swap}{shared_lock}% \begin{itemdecl} @@ -2640,7 +2638,7 @@ \returns The previous value of \tcode{pm}. \pnum -\postconditions \tcode{pm == nullptr} and \tcode{owns == false}. +\ensures \tcode{pm == nullptr} and \tcode{owns == false}. \end{itemdescr} \indexlibrarymember{swap}{shared_lock}% @@ -2654,7 +2652,7 @@ \effects As if by \tcode{x.swap(y)}. \end{itemdescr} -\rSec4[thread.lock.shared.obs]{\tcode{shared_lock} observers} +\rSec4[thread.lock.shared.obs]{Observers} \indexlibrarymember{owns_lock}{shared_lock}% \begin{itemdecl} @@ -2765,7 +2763,7 @@ \pnum\sync The construction of a \tcode{once_flag} object is not synchronized. -\pnum\postconditions The object's internal state is set to indicate to an invocation of +\pnum\ensures The object's internal state is set to indicate to an invocation of \tcode{call_once} with the object as its initial argument that no function has been called. \end{itemdescr} @@ -3073,7 +3071,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum\throws Nothing. @@ -3112,7 +3110,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum @@ -3163,7 +3161,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum @@ -3212,7 +3210,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum @@ -3257,7 +3255,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum @@ -3309,7 +3307,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} +\ensures \tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is locked by the calling thread. \pnum @@ -3448,7 +3446,7 @@ shall be called\iref{except.terminate}. \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} -\pnum\postconditions \tcode{lock} is locked by the calling thread. +\pnum\ensures \tcode{lock} is locked by the calling thread. \pnum\throws Nothing. @@ -3501,7 +3499,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock} is locked by the calling thread. +\ensures \tcode{lock} is locked by the calling thread. \pnum \returns \tcode{cv_status::timeout} if @@ -3539,7 +3537,7 @@ \begin{note} This can happen if the re-locking of the mutex throws an exception. \end{note} \pnum -\postconditions \tcode{lock} is locked by the calling thread. +\ensures \tcode{lock} is locked by the calling thread. \pnum \throws Timeout-related @@ -3964,7 +3962,7 @@ of \tcode{rhs} (if any) to the newly-constructed object. \pnum -\postconditions \tcode{rhs} has no shared state. +\ensures \tcode{rhs} has no shared state. \end{itemdescr} \indexlibrary{\idxcode{promise}!destructor}% @@ -4003,7 +4001,7 @@ \effects Exchanges the shared state of \tcode{*this} and \tcode{other}. \pnum -\postconditions \tcode{*this} has the shared state (if any) that \tcode{other} had +\ensures \tcode{*this} has the shared state (if any) that \tcode{other} had prior to the call to \tcode{swap}. \tcode{other} has the shared state (if any) that \tcode{*this} had prior to the call to \tcode{swap}. \end{itemdescr} @@ -4018,6 +4016,17 @@ \returns A \tcode{future} object with the same shared state as \tcode{*this}. +\pnum +\sync Calls to this function do not introduce +data races~\iref{intro.multithread} with calls to +\tcode{set_value}, +\tcode{set_exception}, +\tcode{set_value_at_thread_exit}, or +\tcode{set_exception_at_thread_exit}. +\begin{note} +Such calls need not synchronize with each other. +\end{note} + \pnum \throws \tcode{future_error} if \tcode{*this} has no shared state or if \tcode{get_future} has already been called on a \tcode{promise} with the same @@ -4242,7 +4251,7 @@ shared state. \pnum -\postconditions \tcode{valid() == false}. +\ensures \tcode{valid() == false}. \end{itemdescr} \indexlibrary{\idxcode{future}!constructor}% @@ -4257,7 +4266,7 @@ was originally referred to by \tcode{rhs} (if any). \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{valid()} returns the same value as \tcode{rhs.valid()} prior to the constructor invocation. @@ -4297,7 +4306,7 @@ \end{itemize} \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{valid()} returns the same value as \tcode{rhs.valid()} prior to the @@ -4318,7 +4327,7 @@ \returns \tcode{shared_future(std::move(*this))}. \pnum -\postconditions \tcode{valid() == false}. +\ensures \tcode{valid() == false}. \end{itemdescr} \indexlibrarymember{get}{future}% @@ -4361,7 +4370,7 @@ \throws The stored exception, if an exception was stored in the shared state. \pnum -\postconditions \tcode{valid() == false}. +\ensures \tcode{valid() == false}. \end{itemdescr} \indexlibrarymember{valid}{future}% @@ -4528,7 +4537,7 @@ shared state. \pnum -\postconditions \tcode{valid() == false}. +\ensures \tcode{valid() == false}. \end{itemdescr} \indexlibrary{\idxcode{shared_future}!constructor}% @@ -4542,7 +4551,7 @@ shared state as \tcode{rhs} (if any). \pnum -\postconditions \tcode{valid()} returns the same value as \tcode{rhs.valid()}. +\ensures \tcode{valid()} returns the same value as \tcode{rhs.valid()}. \end{itemdescr} \indexlibrary{\idxcode{shared_future}!constructor}% @@ -4557,7 +4566,7 @@ shared state that was originally referred to by \tcode{rhs} (if any). \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{valid()} returns the same value as \tcode{rhs.valid()} returned prior to the constructor invocation. @@ -4597,7 +4606,7 @@ \end{itemize} \pnum -\postconditions +\ensures \begin{itemize} \item \tcode{valid()} returns the same value as \tcode{rhs.valid()} returned prior to @@ -4626,7 +4635,7 @@ \end{itemize} \pnum -\postconditions \tcode{valid() == rhs.valid()}. +\ensures \tcode{valid() == rhs.valid()}. \end{itemdescr} \indexlibrarymember{get}{shared_future}% @@ -4992,7 +5001,7 @@ } \end{codeblock} -\rSec3[futures.task.members]{\tcode{packaged_task} member functions} +\rSec3[futures.task.members]{Member functions} \indexlibrary{\idxcode{packaged_task}!constructor}% \begin{itemdecl} @@ -5045,7 +5054,7 @@ shared state. Moves the stored task from \tcode{rhs} to \tcode{*this}. \pnum -\postconditions \tcode{rhs} has no shared state. +\ensures \tcode{rhs} has no shared state. \end{itemdescr} \indexlibrarymember{operator=}{packaged_task}% @@ -5085,7 +5094,7 @@ \effects Exchanges the shared states and stored tasks of \tcode{*this} and \tcode{other}. \pnum -\postconditions \tcode{*this} has the same shared state +\ensures \tcode{*this} has the same shared state and stored task (if any) as \tcode{other} prior to the call to \tcode{swap}. \tcode{other} has the same shared state and stored task (if any) @@ -5111,6 +5120,15 @@ \pnum \returns A \tcode{future} object that shares the same shared state as \tcode{*this}. +\pnum +\sync Calls to this function do not introduce +data races~\iref{intro.multithread} with calls to +\tcode{operator()} or +\tcode{make_ready_at_thread_exit}. +\begin{note} +Such calls need not synchronize with each other. +\end{note} + \pnum \throws A \tcode{future_error} object if an error occurs. @@ -5205,7 +5223,7 @@ \end{itemize} \end{itemdescr} -\rSec3[futures.task.nonmembers]{\tcode{packaged_task} globals} +\rSec3[futures.task.nonmembers]{Globals} \indexlibrarymember{swap}{packaged_task}% \begin{itemdecl} diff --git a/source/time.tex b/source/time.tex index db718f9034..8c213eb35f 100644 --- a/source/time.tex +++ b/source/time.tex @@ -313,8 +313,8 @@ basic_string* abbrev = nullptr, minutes* offset = nullptr); - // \ref{time.clock.file}, class \tcode{file_clock} - class file_clock; + // \ref{time.clock.file}, type \tcode{file_clock} + using file_clock = @\seebelow@; template using file_time = time_point; @@ -1133,9 +1133,9 @@ template struct duration_values { public: - static constexpr Rep zero(); - static constexpr Rep min(); - static constexpr Rep max(); + static constexpr Rep zero() noexcept; + static constexpr Rep min() noexcept; + static constexpr Rep max() noexcept; }; \end{itemdecl} @@ -1149,7 +1149,7 @@ \indexlibrarymember{zero}{duration_values}% \begin{itemdecl} -static constexpr Rep zero(); +static constexpr Rep zero() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1164,7 +1164,7 @@ \indexlibrarymember{min}{duration_values}% \begin{itemdecl} -static constexpr Rep min(); +static constexpr Rep min() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1177,7 +1177,7 @@ \indexlibrarymember{max}{duration_values}% \begin{itemdecl} -static constexpr Rep max(); +static constexpr Rep max() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1314,9 +1314,9 @@ constexpr duration& operator%=(const duration& rhs); // \ref{time.duration.special}, special values - static constexpr duration zero(); - static constexpr duration min(); - static constexpr duration max(); + static constexpr duration zero() noexcept; + static constexpr duration min() noexcept; + static constexpr duration max() noexcept; }; } \end{codeblock} @@ -1378,7 +1378,7 @@ \effects Constructs an object of type \tcode{duration}. \pnum -\postconditions \tcode{count() == static_cast(r)}. +\ensures \tcode{count() == static_cast(r)}. \end{itemdescr} \indexlibrary{\idxcode{duration}!constructor}% @@ -1573,7 +1573,7 @@ \indexlibrarymember{zero}{duration}% \begin{itemdecl} -static constexpr duration zero(); +static constexpr duration zero() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1583,7 +1583,7 @@ \indexlibrarymember{min}{duration}% \begin{itemdecl} -static constexpr duration min(); +static constexpr duration min() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1593,7 +1593,7 @@ \indexlibrarymember{max}{duration}% \begin{itemdecl} -static constexpr duration max(); +static constexpr duration max() noexcept; \end{itemdecl} \begin{itemdescr} @@ -2186,8 +2186,8 @@ constexpr time_point& operator-=(const duration& d); // \ref{time.point.special}, special values - static constexpr time_point min(); - static constexpr time_point max(); + static constexpr time_point min() noexcept; + static constexpr time_point max() noexcept; }; } \end{codeblock} @@ -2333,7 +2333,7 @@ \indexlibrarymember{min}{time_point}% \begin{itemdecl} -static constexpr time_point min(); +static constexpr time_point min() noexcept; \end{itemdecl} \begin{itemdescr} @@ -2343,7 +2343,7 @@ \indexlibrarymember{max}{time_point}% \begin{itemdecl} -static constexpr time_point max(); +static constexpr time_point max() noexcept; \end{itemdecl} \begin{itemdescr} @@ -2902,7 +2902,7 @@ Produces this output: -\begin{codeblock} +\begin{outputblock} 2015-06-30 23:59:59.500 UTC 2015-06-30 23:59:59.750 UTC 2015-06-30 23:59:60.000 UTC @@ -2911,7 +2911,7 @@ 2015-06-30 23:59:60.750 UTC 2015-07-01 00:00:00.000 UTC 2015-07-01 00:00:00.250 UTC -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -2976,10 +2976,10 @@ \pnum The clock \tcode{tai_clock} measures seconds since 1958-01-01 00:00:00 and is offset 10s ahead of UTC at this date. -That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC. -Leap seconds are not inserted into TAI. +That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC\@. +Leap seconds are not inserted into TAI\@. Therefore every time a leap second is inserted into UTC, -UTC falls another second behind TAI. +UTC falls another second behind TAI\@. For example by 2000-01-01 there had been 22 leap seconds inserted so 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI (22s plus the initial 10s offset). @@ -3100,9 +3100,9 @@ Produces this output: -\begin{codeblock} +\begin{outputblock} 2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -3165,10 +3165,10 @@ \pnum The clock \tcode{gps_clock} measures -seconds since the first Sunday of January, 1980 00:00:00 UTC. -Leap seconds are not inserted into GPS. +seconds since the first Sunday of January, 1980 00:00:00 UTC\@. +Leap seconds are not inserted into GPS\@. Therefore every time a leap second is inserted into UTC, -UTC falls another second behind GPS. +UTC falls another second behind GPS\@. Aside from the offset from \tcode{1958y/January/1} to \tcode{1980y/January/Sunday[1]}, GPS is behind TAI by 19s due to the 10s offset between 1958 and 1970 and the additional 9 leap seconds inserted between 1970 and 1980. @@ -3287,9 +3287,9 @@ Produces this output: -\begin{codeblock} +\begin{outputblock} 2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -3323,46 +3323,36 @@ \returns \tcode{is}. \end{itemdescr} -\rSec2[time.clock.file]{Class \tcode{file_clock}} +\rSec2[time.clock.file]{Type \tcode{file_clock}} \rSec3[time.clock.file.overview]{Overview} \indexlibrary{\idxcode{file_clock}}% \begin{codeblock} namespace std::chrono { - class file_clock { - public: - using rep = @\textit{a signed arithmetic type}@; - using period = ratio<@\unspecnc@, @\unspec@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec@; - - static time_point now() noexcept; - - // Conversion functions, see below - }; + using file_clock = @\seebelow@; } \end{codeblock} \pnum -The clock \tcode{file_clock} is used to create the \tcode{time_point} system -used for \tcode{file_time_type}\iref{filesystems}. Its epoch is unspecified. +\tcode{file_clock} is an alias for a type +meeting the \oldconcept{TrivialClock} requirements\iref{time.clock.req}, and +using a signed arithmetic type for \tcode{file_clock::rep}. +\tcode{file_clock} is used to create the \tcode{time_point} system +used for \tcode{file_time_type}\iref{filesystems}. +Its epoch is unspecified, and +\tcode{noexcept(file_clock::now())} is \tcode{true}. +\begin{note} +The type that \tcode{file_clock} denotes may be +in a different namespace than \tcode{std::chrono}, +such as \tcode{std::filesystem}. +\end{note} \rSec3[time.clock.file.members]{Member functions} \indexlibrarymember{now}{file_clock}% -\begin{itemdecl} -static time_point now(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns A \tcode{file_clock::time_point} indicating the current time. -\end{itemdescr} - \pnum -The class \tcode{file_clock} shall provide +The type denoted by \tcode{file_clock} provides precisely one of the following two sets of static member functions: \begin{codeblock} @@ -3974,7 +3964,7 @@ unsigned char d_; // \expos public: day() = default; - explicit constexpr day(unsigned d) noexcept; + constexpr explicit day(unsigned d) noexcept; constexpr day& operator++() noexcept; constexpr day operator++(int) noexcept; @@ -3984,7 +3974,7 @@ constexpr day& operator+=(const days& d) noexcept; constexpr day& operator-=(const days& d) noexcept; - explicit constexpr operator unsigned() const noexcept; + constexpr explicit operator unsigned() const noexcept; constexpr bool ok() const noexcept; }; } @@ -4008,7 +3998,7 @@ \indexlibrary{\idxcode{day}!constructor}% \begin{itemdecl} -explicit constexpr day(unsigned d) noexcept; +constexpr explicit day(unsigned d) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4099,7 +4089,7 @@ \indexlibrarymember{operator unsigned}{day}% \begin{itemdecl} -explicit constexpr operator unsigned() const noexcept; +constexpr explicit operator unsigned() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4264,7 +4254,7 @@ unsigned char m_; // \expos public: month() = default; - explicit constexpr month(unsigned m) noexcept; + constexpr explicit month(unsigned m) noexcept; constexpr month& operator++() noexcept; constexpr month operator++(int) noexcept; @@ -4274,7 +4264,7 @@ constexpr month& operator+=(const months& m) noexcept; constexpr month& operator-=(const months& m) noexcept; - explicit constexpr operator unsigned() const noexcept; + constexpr explicit operator unsigned() const noexcept; constexpr bool ok() const noexcept; }; } @@ -4298,7 +4288,7 @@ \indexlibrary{\idxcode{month}!constructor}% \begin{itemdecl} -explicit constexpr month(unsigned m) noexcept; +constexpr explicit month(unsigned m) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4389,7 +4379,7 @@ \indexlibrarymember{operator unsigned}{month}% \begin{itemdecl} -explicit constexpr month::operator unsigned() const noexcept; +constexpr explicit month::operator unsigned() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4567,7 +4557,7 @@ short y_; // \expos public: year() = default; - explicit constexpr year(int y) noexcept; + constexpr explicit year(int y) noexcept; constexpr year& operator++() noexcept; constexpr year operator++(int) noexcept; @@ -4582,7 +4572,7 @@ constexpr bool is_leap() const noexcept; - explicit constexpr operator int() const noexcept; + constexpr explicit operator int() const noexcept; constexpr bool ok() const noexcept; static constexpr year min() noexcept; @@ -4608,7 +4598,7 @@ \indexlibrary{\idxcode{year}!constructor}% \begin{itemdecl} -explicit constexpr year(int y) noexcept; +constexpr explicit year(int y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4729,7 +4719,7 @@ \indexlibrarymember{operator int}{year}% \begin{itemdecl} -explicit constexpr operator int() const noexcept; +constexpr explicit operator int() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4914,9 +4904,9 @@ unsigned char wd_; // \expos public: weekday() = default; - explicit constexpr weekday(unsigned wd) noexcept; + constexpr explicit weekday(unsigned wd) noexcept; constexpr weekday(const sys_days& dp) noexcept; - explicit constexpr weekday(const local_days& dp) noexcept; + constexpr explicit weekday(const local_days& dp) noexcept; constexpr weekday& operator++() noexcept; constexpr weekday operator++(int) noexcept; @@ -4926,7 +4916,7 @@ constexpr weekday& operator+=(const days& d) noexcept; constexpr weekday& operator-=(const days& d) noexcept; - explicit constexpr operator unsigned() const noexcept; + constexpr explicit operator unsigned() const noexcept; constexpr bool ok() const noexcept; constexpr weekday_indexed operator[](unsigned index) const noexcept; @@ -4958,7 +4948,7 @@ \indexlibrary{\idxcode{weekday}!constructor}% \begin{itemdecl} -explicit constexpr weekday(unsigned wd) noexcept; +constexpr explicit weekday(unsigned wd) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4991,7 +4981,7 @@ \indexlibrary{\idxcode{weekday}!constructor}% \begin{itemdecl} -explicit constexpr weekday(const local_days& dp) noexcept; +constexpr explicit weekday(const local_days& dp) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5087,7 +5077,7 @@ \indexlibrarymember{operator unsigned}{weekday}% \begin{itemdecl} -explicit constexpr operator unsigned() const noexcept; +constexpr explicit operator unsigned() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5397,7 +5387,7 @@ chrono::weekday wd_; // \expos public: - explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; + constexpr explicit weekday_last(const chrono::weekday& wd) noexcept; constexpr chrono::weekday weekday() const noexcept; constexpr bool ok() const noexcept; @@ -5427,7 +5417,7 @@ \indexlibrary{\idxcode{weekday_last}!constructor}% \begin{itemdecl} -explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; +constexpr explicit weekday_last(const chrono::weekday& wd) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5655,7 +5645,7 @@ chrono::month m_; // \expos public: - explicit constexpr month_day_last(const chrono::month& m) noexcept; + constexpr explicit month_day_last(const chrono::month& m) noexcept; constexpr chrono::month month() const noexcept; constexpr bool ok() const noexcept; @@ -5684,7 +5674,7 @@ \indexlibrary{\idxcode{month_day_last}!constructor}% \begin{itemdecl} -explicit constexpr month_day_last(const chrono::month& m) noexcept; +constexpr explicit month_day_last(const chrono::month& m) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6272,7 +6262,7 @@ const chrono::day& d) noexcept; constexpr year_month_day(const year_month_day_last& ymdl) noexcept; constexpr year_month_day(const sys_days& dp) noexcept; - explicit constexpr year_month_day(const local_days& dp) noexcept; + constexpr explicit year_month_day(const local_days& dp) noexcept; constexpr year_month_day& operator+=(const months& m) noexcept; constexpr year_month_day& operator-=(const months& m) noexcept; @@ -6284,7 +6274,7 @@ constexpr chrono::day day() const noexcept; constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; } @@ -6364,7 +6354,7 @@ \indexlibrary{\idxcode{year_month_day}!constructor}% \begin{itemdecl} -explicit constexpr year_month_day(const local_days& dp) noexcept; +constexpr explicit year_month_day(const local_days& dp) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6496,7 +6486,7 @@ \indexlibrarymember{operator local_days}{year_month_day}% \begin{itemdecl} -explicit constexpr operator local_days() const noexcept; +constexpr explicit operator local_days() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -6710,7 +6700,7 @@ constexpr chrono::day day() const noexcept; constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; } @@ -6858,7 +6848,7 @@ \indexlibrarymember{operator local_days}{year_month_day_last}% \begin{itemdecl} -explicit constexpr operator local_days() const noexcept; +constexpr explicit operator local_days() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -6996,7 +6986,7 @@ constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; constexpr year_month_weekday(const sys_days& dp) noexcept; - explicit constexpr year_month_weekday(const local_days& dp) noexcept; + constexpr explicit year_month_weekday(const local_days& dp) noexcept; constexpr year_month_weekday& operator+=(const months& m) noexcept; constexpr year_month_weekday& operator-=(const months& m) noexcept; @@ -7010,7 +7000,7 @@ constexpr chrono::weekday_indexed weekday_indexed() const noexcept; constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; } @@ -7066,7 +7056,7 @@ \indexlibrary{\idxcode{year_month_weekday}!constructor}% \begin{itemdecl} -explicit constexpr year_month_weekday(const local_days& dp) noexcept; +constexpr explicit year_month_weekday(const local_days& dp) noexcept; \end{itemdecl} \begin{itemdescr} @@ -7203,7 +7193,7 @@ \indexlibrarymember{operator local_days}{year_month_weekday}% \begin{itemdecl} -explicit constexpr operator local_days() const noexcept; +constexpr explicit operator local_days() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -7343,7 +7333,7 @@ constexpr chrono::weekday_last weekday_last() const noexcept; constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; } @@ -7488,7 +7478,7 @@ \indexlibrarymember{operator local_days}{year_month_weekday_last}% \begin{itemdecl} -explicit constexpr operator local_days() const noexcept; +constexpr explicit operator local_days() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -8102,11 +8092,11 @@ using precision = chrono::hours; time_of_day() = default; - explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; + constexpr explicit time_of_day(chrono::hours since_midnight) noexcept; constexpr chrono::hours hours() const noexcept; - explicit constexpr operator precision() const noexcept; + constexpr explicit operator precision() const noexcept; constexpr precision to_duration() const noexcept; constexpr void make24() noexcept; @@ -8122,7 +8112,7 @@ \indexlibrary{\idxcode{time_of_day}!constructor}% \begin{itemdecl} -explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; +constexpr explicit time_of_day(chrono::hours since_midnight) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8132,7 +8122,7 @@ corresponding to \tcode{since_midnight} hours after 00:00:00. \pnum -\postconditions +\ensures \tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. \end{itemdescr} @@ -8148,7 +8138,7 @@ \indexlibrarymember{operator precision}{time_of_day}% \begin{itemdecl} -explicit constexpr operator precision() const noexcept; +constexpr explicit operator precision() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -8203,12 +8193,12 @@ using precision = chrono::minutes; time_of_day() = default; - explicit constexpr time_of_day(chrono::minutes since_midnight) noexcept; + constexpr explicit time_of_day(chrono::minutes since_midnight) noexcept; constexpr chrono::hours hours() const noexcept; constexpr chrono::minutes minutes() const noexcept; - explicit constexpr operator precision() const noexcept; + constexpr explicit operator precision() const noexcept; constexpr precision to_duration() const noexcept; constexpr void make24() noexcept; @@ -8224,7 +8214,7 @@ \indexlibrary{\idxcode{time_of_day}!constructor}% \begin{itemdecl} -explicit constexpr time_of_day(minutes since_midnight) noexcept; +constexpr explicit time_of_day(minutes since_midnight) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8235,7 +8225,7 @@ corresponding to \tcode{since_midnight} minutes after 00:00:00. \pnum -\postconditions +\ensures \tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. \tcode{minutes()} returns the integral number of minutes @@ -8264,7 +8254,7 @@ \indexlibrarymember{operator precision}{time_of_day}% \begin{itemdecl} -explicit constexpr operator precision() const noexcept; +constexpr explicit operator precision() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -8319,13 +8309,13 @@ using precision = chrono::seconds; time_of_day() = default; - explicit constexpr time_of_day(chrono::seconds since_midnight) noexcept; + constexpr explicit time_of_day(chrono::seconds since_midnight) noexcept; constexpr chrono::hours hours() const noexcept; constexpr chrono::minutes minutes() const noexcept; constexpr chrono::seconds seconds() const noexcept; - explicit constexpr operator precision() const noexcept; + constexpr explicit operator precision() const noexcept; constexpr precision to_duration() const noexcept; constexpr void make24() noexcept; @@ -8341,7 +8331,7 @@ \indexlibrary{\idxcode{time_of_day}!constructor}% \begin{itemdecl} -explicit constexpr time_of_day(seconds since_midnight) noexcept; +constexpr explicit time_of_day(seconds since_midnight) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8352,7 +8342,7 @@ corresponding to \tcode{since_midnight} seconds after 00:00:00. \pnum -\postconditions +\ensures \tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. \tcode{minutes()} returns the integral number of minutes @@ -8396,7 +8386,7 @@ \indexlibrarymember{operator precision}{time_of_day}% \begin{itemdecl} -explicit constexpr operator precision() const noexcept; +constexpr explicit operator precision() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -8452,14 +8442,14 @@ using precision = duration; time_of_day() = default; - explicit constexpr time_of_day(precision since_midnight) noexcept; + constexpr explicit time_of_day(precision since_midnight) noexcept; constexpr chrono::hours hours() const noexcept; constexpr chrono::minutes minutes() const noexcept; constexpr chrono::seconds seconds() const noexcept; constexpr precision subseconds() const noexcept; - explicit constexpr operator precision() const noexcept; + constexpr explicit operator precision() const noexcept; constexpr precision to_duration() const noexcept; constexpr void make24() noexcept; @@ -8480,7 +8470,7 @@ \indexlibrary{\idxcode{time_of_day<\placeholder{sub-second duration}>}!constructor}% \begin{itemdecl} -explicit constexpr time_of_day(precision since_midnight) noexcept; +constexpr explicit time_of_day(precision since_midnight) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8491,7 +8481,7 @@ corresponding to \tcode{since_midnight} fractional seconds after 00:00:00. \pnum -\postconditions +\ensures \tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. \tcode{minutes()} returns the integral number of minutes @@ -8548,7 +8538,7 @@ \indexlibrarymember{operator precision}{time_of_day<\placeholder{sub-second duration}>}% \begin{itemdecl} -explicit constexpr operator precision() const noexcept; +constexpr explicit operator precision() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -8628,12 +8618,12 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 0100 1am 1800 6pm -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -8669,12 +8659,12 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 01:08 1:08am 18:15 6:15pm -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -8710,12 +8700,12 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 01:08:03 1:08:03am 18:15:45 6:15:45pm -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -8751,12 +8741,12 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 01:08:03.007 1:08:03.007am 18:15:45.123 6:15:45.123pm -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -9174,12 +9164,12 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 2016-03-13 02:30:00 is in a gap between 2016-03-13 02:00:00 EST and 2016-03-13 03:00:00 EDT which are both equivalent to 2016-03-13 07:00:00 UTC -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -9247,11 +9237,11 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 2016-11-06 01:30:00 is ambiguous. It could be 2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or 2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -10187,7 +10177,7 @@ Produces the output: -\begin{codeblock} +\begin{outputblock} 1972-07-01 00:00:00 1973-01-01 00:00:00 1974-01-01 00:00:00 @@ -10215,7 +10205,7 @@ 2012-07-01 00:00:00 2015-07-01 00:00:00 2017-01-01 00:00:00 -\end{codeblock} +\end{outputblock} \end{example} \rSec3[time.zone.leap.members]{Member functions} @@ -10814,7 +10804,7 @@ \\ \rowsep \tcode{\%z} & The offset from UTC in the ISO 8601 format. -For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC. +For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC\@. If the offset is zero, \tcode{+0000} is used. The modified commands \tcode{\%Ez} and \tcode{\%Oz} insert a \tcode{:} between the hours and minutes: \tcode{-04:30}. @@ -10876,7 +10866,7 @@ \remarks This function shall not participate in overload resolution unless \begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp, &abbrev) +from_stream(declval&>(), fmt.c_str(), tp, addressof(abbrev)) \end{codeblock} is a valid expression. @@ -10884,7 +10874,7 @@ \returns A manipulator that, when extracted from a \tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev)}. +calls \tcode{from_stream(is, fmt.c_str(), tp, addressof(abbrev))}. \end{itemdescr} \begin{itemdecl} @@ -10922,7 +10912,8 @@ \remarks This function shall not participate in overload resolution unless \begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp, &abbrev, &offset) +from_stream(declval&>(), + fmt.c_str(), tp, addressof(abbrev), &offset) \end{codeblock} is a valid expression. @@ -10930,7 +10921,7 @@ \returns A manipulator that, when extracted from a \tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev, \&offset)}. +calls \tcode{from_stream(is, fmt.c_str(), tp, addressof(abbrev), \&offset)}. \end{itemdescr} \pnum @@ -11190,7 +11181,7 @@ \tcode{\%z} & The offset from UTC in the format \tcode{[+|-]hh[mm]}. For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC, -and \tcode{04} refers to 4 hours ahead of UTC. +and \tcode{04} refers to 4 hours ahead of UTC\@. The modified commands \tcode{\%Ez} and \tcode{\%Oz} parse a \tcode{:} between the hours and minutes and render leading zeroes on the hour field optional: diff --git a/source/utilities.tex b/source/utilities.tex index d37a521068..67562258ff 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -114,7 +114,7 @@ constexpr bool operator>=(const pair&, const pair&); template - void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); template constexpr @\seebelow@ make_pair(T1&&, T2&&); @@ -479,25 +479,26 @@ pair(const pair&) = default; pair(pair&&) = default; - explicit(@\seebelow@) constexpr pair(); - explicit(@\seebelow@) constexpr pair(const T1& x, const T2& y); + constexpr explicit(@\seebelow@) pair(); + constexpr explicit(@\seebelow@) pair(const T1& x, const T2& y); template - explicit(@\seebelow@) constexpr pair(U1&& x, U2&& y); + constexpr explicit(@\seebelow@) pair(U1&& x, U2&& y); template - explicit(@\seebelow@) constexpr pair(const pair& p); + constexpr explicit(@\seebelow@) pair(const pair& p); template - explicit(@\seebelow@) constexpr pair(pair&& p); + constexpr explicit(@\seebelow@) pair(pair&& p); template - pair(piecewise_construct_t, tuple first_args, tuple second_args); + constexpr pair(piecewise_construct_t, + tuple first_args, tuple second_args); - pair& operator=(const pair& p); + constexpr pair& operator=(const pair& p); template - pair& operator=(const pair& p); - pair& operator=(pair&& p) noexcept(@\seebelow@); + constexpr pair& operator=(const pair& p); + constexpr pair& operator=(pair&& p) noexcept(@\seebelow@); template - pair& operator=(pair&& p); + constexpr pair& operator=(pair&& p); - void swap(pair& p) noexcept(@\seebelow@); + constexpr void swap(pair& p) noexcept(@\seebelow@); }; template @@ -522,7 +523,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -explicit(@\seebelow@) constexpr pair(); +constexpr explicit(@\seebelow@) pair(); \end{itemdecl} \begin{itemdescr} @@ -547,7 +548,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -explicit(@\seebelow@) constexpr pair(const T1& x, const T2& y); +constexpr explicit(@\seebelow@) pair(const T1& x, const T2& y); \end{itemdecl} \begin{itemdescr} @@ -568,7 +569,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr pair(U1&& x, U2&& y); +template constexpr explicit(@\seebelow@) pair(U1&& x, U2&& y); \end{itemdecl} \begin{itemdescr} @@ -591,7 +592,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr pair(const pair& p); +template constexpr explicit(@\seebelow@) pair(const pair& p); \end{itemdecl} \begin{itemdescr} @@ -611,7 +612,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr pair(pair&& p); +template constexpr explicit(@\seebelow@) pair(pair&& p); \end{itemdecl} \begin{itemdescr} @@ -635,7 +636,8 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} template - pair(piecewise_construct_t, tuple first_args, tuple second_args); + constexpr pair(piecewise_construct_t, + tuple first_args, tuple second_args); \end{itemdecl} \begin{itemdescr} @@ -656,7 +658,7 @@ \indexlibrarymember{operator=}{pair}% \begin{itemdecl} -pair& operator=(const pair& p); +constexpr pair& operator=(const pair& p); \end{itemdecl} \begin{itemdescr} @@ -674,7 +676,7 @@ \indexlibrarymember{operator=}{pair}% \begin{itemdecl} -template pair& operator=(const pair& p); +template constexpr pair& operator=(const pair& p); \end{itemdecl} \begin{itemdescr} @@ -692,7 +694,7 @@ \indexlibrarymember{operator=}{pair}% \begin{itemdecl} -pair& operator=(pair&& p) noexcept(@\seebelow@); +constexpr pair& operator=(pair&& p) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -718,7 +720,7 @@ \indexlibrarymember{operator=}{pair}% \begin{itemdecl} -template pair& operator=(pair&& p); +template constexpr pair& operator=(pair&& p); \end{itemdecl} \begin{itemdescr} @@ -738,7 +740,7 @@ \indexlibrarymember{swap}{pair}% \begin{itemdecl} -void swap(pair& p) noexcept(@\seebelow@); +constexpr void swap(pair& p) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -833,7 +835,7 @@ \indexlibrary{\idxcode{swap}!\idxcode{pair}}% \begin{itemdecl} template - void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -850,16 +852,16 @@ \indexlibrary{\idxcode{make_pair}}% \begin{itemdecl} template - constexpr pair make_pair(T1&& x, T2&& y); + constexpr pair, unwrap_ref_decay_t> make_pair(T1&& x, T2&& y); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{pair(std::forward(x), std::forward(y))}, -where \tcode{V1} and \tcode{V2} are determined as follows: Let \tcode{Ui} be -\tcode{decay_t} for each \tcode{Ti}. If \tcode{Ui} is a specialization -of \tcode{reference_wrapper}, then \tcode{Vi} is \tcode{Ui::type\&}, -otherwise \tcode{Vi} is \tcode{Ui}. +\returns +\begin{codeblock} +pair, + unwrap_ref_decay_t>(std::forward(x), std::forward(y)) +\end{codeblock} \end{itemdescr} \pnum @@ -997,7 +999,7 @@ inline constexpr @\unspec@ ignore; template - constexpr tuple make_tuple(TTypes&&...); + constexpr tuple...> make_tuple(TTypes&&...); template constexpr tuple forward_as_tuple(TTypes&&...) noexcept; @@ -1072,7 +1074,7 @@ // \ref{tuple.special}, specialized algorithms template - void swap(tuple& x, tuple& y) noexcept(@\seebelow@); + constexpr void swap(tuple& x, tuple& y) noexcept(@\seebelow@); // \ref{tuple.helper}, tuple helper classes template @@ -1089,60 +1091,66 @@ class tuple { public: // \ref{tuple.cnstr}, \tcode{tuple} construction - explicit(@\seebelow@) constexpr tuple(); - explicit(@\seebelow@) constexpr tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} + constexpr explicit(@\seebelow@) tuple(); + constexpr explicit(@\seebelow@) tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} template - explicit(@\seebelow@) constexpr tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} + constexpr explicit(@\seebelow@) tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} tuple(const tuple&) = default; tuple(tuple&&) = default; template - explicit(@\seebelow@) constexpr tuple(const tuple&); + constexpr explicit(@\seebelow@) tuple(const tuple&); template - explicit(@\seebelow@) constexpr tuple(tuple&&); + constexpr explicit(@\seebelow@) tuple(tuple&&); template - explicit(@\seebelow@) constexpr tuple(const pair&); // only if \tcode{sizeof...(Types) == 2} + constexpr explicit(@\seebelow@) tuple(const pair&); // only if \tcode{sizeof...(Types) == 2} template - explicit(@\seebelow@) constexpr tuple(pair&&); // only if \tcode{sizeof...(Types) == 2} + constexpr explicit(@\seebelow@) tuple(pair&&); // only if \tcode{sizeof...(Types) == 2} // allocator-extended constructors template - tuple(allocator_arg_t, const Alloc& a); + constexpr tuple(allocator_arg_t, const Alloc& a); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const Types&...); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const Types&...); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template - tuple(allocator_arg_t, const Alloc& a, const tuple&); + constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template - tuple(allocator_arg_t, const Alloc& a, tuple&&); + constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const tuple&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const tuple&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, tuple&&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, tuple&&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const pair&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, pair&&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, pair&&); // \ref{tuple.assign}, \tcode{tuple} assignment - tuple& operator=(const tuple&); - tuple& operator=(tuple&&) noexcept(@\seebelow@); + constexpr tuple& operator=(const tuple&); + constexpr tuple& operator=(tuple&&) noexcept(@\seebelow@); template - tuple& operator=(const tuple&); + constexpr tuple& operator=(const tuple&); template - tuple& operator=(tuple&&); + constexpr tuple& operator=(tuple&&); template - tuple& operator=(const pair&); // only if \tcode{sizeof...(Types) == 2} + constexpr tuple& operator=(const pair&); // only if \tcode{sizeof...(Types) == 2} template - tuple& operator=(pair&&); // only if \tcode{sizeof...(Types) == 2} + constexpr tuple& operator=(pair&&); // only if \tcode{sizeof...(Types) == 2} // \ref{tuple.swap}, \tcode{tuple} swap - void swap(tuple&) noexcept(@\seebelow@); + constexpr void swap(tuple&) noexcept(@\seebelow@); }; template @@ -1185,7 +1193,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -explicit(@\seebelow@) constexpr tuple(); +constexpr explicit(@\seebelow@) tuple(); \end{itemdecl} \begin{itemdescr} @@ -1207,7 +1215,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -explicit(@\seebelow@) constexpr tuple(const Types&...); +constexpr explicit(@\seebelow@) tuple(const Types&...); \end{itemdecl} \begin{itemdescr} @@ -1227,7 +1235,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr tuple(UTypes&&... u); +template constexpr explicit(@\seebelow@) tuple(UTypes&&... u); \end{itemdecl} \begin{itemdescr} @@ -1276,7 +1284,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr tuple(const tuple& u); +template constexpr explicit(@\seebelow@) tuple(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1305,7 +1313,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr tuple(tuple&& u); +template constexpr explicit(@\seebelow@) tuple(tuple&& u); \end{itemdecl} \begin{itemdescr} @@ -1338,7 +1346,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr tuple(const pair& u); +template constexpr explicit(@\seebelow@) tuple(const pair& u); \end{itemdecl} \begin{itemdescr} @@ -1362,7 +1370,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template explicit(@\seebelow@) constexpr tuple(pair&& u); +template constexpr explicit(@\seebelow@) tuple(pair&& u); \end{itemdecl} \begin{itemdescr} @@ -1387,23 +1395,29 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} template - tuple(allocator_arg_t, const Alloc& a); + constexpr tuple(allocator_arg_t, const Alloc& a); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const Types&...); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const Types&...); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template - tuple(allocator_arg_t, const Alloc& a, const tuple&); + constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template - tuple(allocator_arg_t, const Alloc& a, tuple&&); + constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const tuple&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const tuple&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, tuple&&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, tuple&&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, const pair&); template - explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, pair&&); + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, pair&&); \end{itemdecl} \begin{itemdescr} @@ -1428,7 +1442,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -tuple& operator=(const tuple& u); +constexpr tuple& operator=(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1446,7 +1460,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -tuple& operator=(tuple&& u) noexcept(@\seebelow@); +constexpr tuple& operator=(tuple&& u) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -1473,7 +1487,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -template tuple& operator=(const tuple& u); +template constexpr tuple& operator=(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1492,7 +1506,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -template tuple& operator=(tuple&& u); +template constexpr tuple& operator=(tuple&& u); \end{itemdecl} \begin{itemdescr} @@ -1512,7 +1526,7 @@ \indexlibrarymember{operator=}{tuple}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template tuple& operator=(const pair& u); +template constexpr tuple& operator=(const pair& u); \end{itemdecl} \begin{itemdescr} @@ -1534,7 +1548,7 @@ \indexlibrarymember{operator=}{tuple}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template tuple& operator=(pair&& u); +template constexpr tuple& operator=(pair&& u); \end{itemdecl} \begin{itemdescr} @@ -1559,7 +1573,7 @@ \indexlibrarymember{swap}{tuple}% \begin{itemdecl} -void swap(tuple& rhs) noexcept(@\seebelow@); +constexpr void swap(tuple& rhs) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -1596,18 +1610,12 @@ \indexlibrary{\idxcode{tuple}!\idxcode{make_tuple}}% \begin{itemdecl} template - constexpr tuple make_tuple(TTypes&&... t); + constexpr tuple...> make_tuple(TTypes&&... t); \end{itemdecl} \begin{itemdescr} \pnum -The pack \tcode{VTypes} is defined as follows. Let \tcode{U}$_i$ be \tcode{decay_t} for each -\tcode{T}$_i$ in \tcode{TTypes}. If \tcode{U}$_i$ is a specialization of -\tcode{reference_wrapper}, then \tcode{V}$_i$ in \tcode{VTypes} is \tcode{U$_i$::type\&}, -otherwise \tcode{V}$_i$ is \tcode{U}$_i$. - -\pnum -\returns \tcode{tuple(std::forward(t)...)}. +\returns \tcode{tuple...>(std::forward(t)...)}. \pnum \begin{example} @@ -1842,8 +1850,9 @@ \pnum In addition to being available via inclusion of the \tcode{} header, -the three templates are available when either of the headers \tcode{} or -\tcode{} are included. +the three templates are available +when any of the headers \tcode{}, \tcode{}, or \tcode{} +are included. \end{itemdescr} \indexlibrary{\idxcode{tuple_element}}% @@ -1871,8 +1880,9 @@ \pnum In addition to being available via inclusion of the \tcode{} header, -the three templates are available when either of the headers \tcode{} or -\tcode{} are included. +the three templates are available +when any of the headers \tcode{}, \tcode{}, or \tcode{} +are included. \end{itemdescr} \rSec3[tuple.elem]{Element access} @@ -1903,7 +1913,7 @@ \pnum \begin{note}[Note A] -If a \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, +If a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, the return type is \tcode{X\&}, not \tcode{X\&\&}. However, if the element type is a non-reference type \tcode{T}, the return type is \tcode{T\&\&}. @@ -1911,9 +1921,9 @@ \pnum \begin{note}[Note B] -Constness is shallow. If a \tcode{T} -in \tcode{Types} is some -reference type \tcode{X\&}, the return type is \tcode{X\&}, not \tcode{const X\&}. +Constness is shallow. +If a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, +the return type is \tcode{X\&}, not \tcode{const X\&}. However, if the element type is a non-reference type \tcode{T}, the return type is \tcode{const T\&}. This is consistent with how constness is defined to work @@ -1935,12 +1945,12 @@ \begin{itemdescr} \pnum -\requires The type \tcode{T} occurs exactly once in \tcode{Types...}. +\requires The type \tcode{T} occurs exactly once in \tcode{Types}. Otherwise, the program is ill-formed. \pnum \returns A reference to the element of \tcode{t} corresponding to the type -\tcode{T} in \tcode{Types...}. +\tcode{T} in \tcode{Types}. \pnum \begin{example} @@ -2085,14 +2095,14 @@ \indexlibrary{\idxcode{swap}}% \begin{itemdecl} template - void swap(tuple& x, tuple& y) noexcept(@\seebelow@); + constexpr void swap(tuple& x, tuple& y) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum \remarks This function shall not participate in overload resolution -unless \tcode{is_swappable_v<$\tcode{T}_i$>} is \tcode{true} -for all $i$, where $0 \leq i < \tcode{sizeof...(Types)}$. +unless \tcode{is_swappable_v} is \tcode{true} +for every type \tcode{T} in \tcode{Types}. The expression inside \tcode{noexcept} is equivalent to: \begin{codeblock} @@ -2224,8 +2234,8 @@ // \ref{optional.assign}, assignment optional& operator=(nullopt_t) noexcept; - optional& operator=(const optional&); - optional& operator=(optional&&) noexcept(@\seebelow@); + constexpr optional& operator=(const optional&); + constexpr optional& operator=(optional&&) noexcept(@\seebelow@); template optional& operator=(U&&); template optional& operator=(const optional&); template optional& operator=(optional&&); @@ -2292,7 +2302,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{*this} does not contain a value. \pnum @@ -2313,7 +2323,7 @@ direct-non-list-initializing an object of type \tcode{T} with the expression \tcode{*rhs}. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2325,7 +2335,7 @@ This constructor shall be defined as deleted unless \tcode{is_copy_constructible_v} is \tcode{true}. If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, -this constructor shall be a \tcode{constexpr} constructor. +this constructor is trivial.. \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% @@ -2341,7 +2351,7 @@ \tcode{bool(rhs)} is unchanged. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2355,7 +2365,7 @@ This constructor shall not participate in overload resolution unless \tcode{is_move_constructible_v} is \tcode{true}. If \tcode{is_trivially_move_constructible_v} is \tcode{true}, -this constructor shall be a \tcode{constexpr} constructor. +this constructor is trivial. \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% @@ -2369,7 +2379,7 @@ Initializes the contained value as if direct-non-list-initializing an object of type \tcode{T} with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -2395,7 +2405,7 @@ Initializes the contained value as if direct-non-list-initializing an object of type \tcode{T} with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -2420,7 +2430,7 @@ an object of type \tcode{T} with the expression \tcode{std::forward(v)}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -2454,7 +2464,7 @@ an object of type \tcode{T} with the expression \tcode{*rhs}. \pnum -\postconditions +\ensures \tcode{bool(rhs)} == \tcode{bool(*this)}. \pnum @@ -2495,7 +2505,7 @@ \tcode{bool(rhs)} is unchanged. \pnum -\postconditions +\ensures \tcode{bool(rhs)} == \tcode{bool(*this)}. \pnum @@ -2559,13 +2569,13 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{*this} does not contain a value. \end{itemdescr} \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -optional& operator=(const optional& rhs); +constexpr optional& operator=(const optional& rhs); \end{itemdecl} \begin{itemdescr} @@ -2591,7 +2601,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2603,11 +2613,15 @@ This operator shall be defined as deleted unless \tcode{is_copy_constructible_v} is \tcode{true} and \tcode{is_copy_assignable_v} is \tcode{true}. +If \tcode{is_trivially_copy_constructible_v \&\&} +\tcode{is_trivially_copy_assignable_v \&\&} +\tcode{is_trivially_destructible_v} is \tcode{true}, +this assignment operator is trivial. \end{itemdescr} \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -optional& operator=(optional&& rhs) noexcept(@\seebelow@); +constexpr optional& operator=(optional&& rhs) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -2634,7 +2648,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2653,6 +2667,10 @@ This operator shall not participate in overload resolution unless \tcode{is_move_constructible_v} is \tcode{true} and \tcode{is_move_assignable_v} is \tcode{true}. +If \tcode{is_trivially_move_constructible_v \&\&} +\tcode{is_trivially_move_assignable_v \&\&} +\tcode{is_trivially_destructible_v} is \tcode{true}, +this assignment operator is trivial. \end{itemdescr} \indexlibrarymember{operator=}{optional}% @@ -2670,7 +2688,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -2712,7 +2730,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2774,7 +2792,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures \tcode{bool(rhs) == bool(*this)}. \pnum @@ -2821,7 +2839,7 @@ Calls \tcode{*this = nullopt}. Then initializes the contained value as if direct-non-list-initializing an object of type \tcode{T} with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -2848,7 +2866,7 @@ Calls \tcode{*this = nullopt}. Then initializes the contained value as if direct-non-list-initializing an object of type \tcode{T} with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{*this} contains a value. \pnum @@ -3094,7 +3112,7 @@ otherwise no effect. \pnum -\postconditions +\ensures \tcode{*this} does not contain a value. \end{itemdescr} @@ -3139,7 +3157,7 @@ Constructs an object of class \tcode{bad_optional_access}. \pnum -\postconditions +\ensures \tcode{what()} returns an \impldef{return value of \tcode{bad_optional_access::what}} \ntbs{}. @@ -3767,6 +3785,8 @@ // \ref{variant.visit}, visitation template constexpr @\seebelow@ visit(Visitor&&, Variants&&...); + template + constexpr R visit(Visitor&&, Variants&&...); // \ref{variant.monostate}, class \tcode{monostate} struct monostate; @@ -3803,8 +3823,8 @@ public: // \ref{variant.ctor}, constructors constexpr variant() noexcept(@\seebelow@); - variant(const variant&); - variant(variant&&) noexcept(@\seebelow@); + constexpr variant(const variant&); + constexpr variant(variant&&) noexcept(@\seebelow@); template constexpr variant(T&&) noexcept(@\seebelow@); @@ -3823,8 +3843,8 @@ ~variant(); // \ref{variant.assign}, assignment - variant& operator=(const variant&); - variant& operator=(variant&&) noexcept(@\seebelow@); + constexpr variant& operator=(const variant&); + constexpr variant& operator=(variant&&) noexcept(@\seebelow@); template variant& operator=(T&&) noexcept(@\seebelow@); @@ -3858,12 +3878,10 @@ Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. The contained value shall be allocated in a region of the \tcode{variant} -storage suitably aligned for all types in \tcode{Types...}. -It is \impldef{whether \tcode{variant} supports over-aligned types} -whether over-aligned types are supported. +storage suitably aligned for all types in \tcode{Types}. \pnum -All types in \tcode{Types...} shall be (possibly cv-qualified) +All types in \tcode{Types} shall be (possibly cv-qualified) object types that are not arrays. \pnum @@ -3874,7 +3892,7 @@ \pnum In the descriptions that follow, let $i$ be in the range \range{0}{sizeof...(Types)}, -and $\tcode{T}_i$ be the $i^\text{th}$ type in \tcode{Types...}. +and $\tcode{T}_i$ be the $i^\text{th}$ type in \tcode{Types}. \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} @@ -3887,7 +3905,7 @@ Constructs a \tcode{variant} holding a value-initialized value of type $\tcode{T}_0$. \pnum -\postconditions +\ensures \tcode{valueless_by_exception()} is \tcode{false} and \tcode{index()} is \tcode{0}. \pnum @@ -3908,7 +3926,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -variant(const variant& w); +constexpr variant(const variant& w); \end{itemdecl} \begin{itemdescr} @@ -3927,11 +3945,13 @@ \remarks This constructor shall be defined as deleted unless \tcode{is_copy_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. +If \tcode{is_trivially_copy_constructible_v<$\tcode{T}_i$>} +is \tcode{true} for all $i$, this constructor is trivial. \end{itemdescr} \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -variant(variant&& w) noexcept(@\seebelow@); +constexpr variant(variant&& w) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -3948,10 +3968,12 @@ \pnum \remarks -The expression inside \tcode{noexcept} is equivalent to the logical AND of +The expression inside \tcode{noexcept} is equivalent to the logical \logop{AND} of \tcode{is_nothrow_move_constructible_v<$\tcode{T}_i$>} for all $i$. This function shall not participate in overload resolution unless \tcode{is_move_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. +If \tcode{is_trivially_move_constructible_v<$\tcode{T}_i$>} +is \tcode{true} for all $i$, this constructor is trivial. \end{itemdescr} \indexlibrary{\idxcode{variant}!constructor}% @@ -3962,7 +3984,12 @@ \begin{itemdescr} \pnum Let $\tcode{T}_j$ be a type that is determined as follows: -build an imaginary function \tcode{\placeholdernc{FUN}($\tcode{T}_i$)} for each alternative type $\tcode{T}_i$. The overload \tcode{\placeholdernc{FUN}($\tcode{T}_j$)} selected by overload +build an imaginary function \tcode{\placeholdernc{FUN}($\tcode{T}_i$)} +for each alternative type $\tcode{T}_i$ +for which \tcode{$\tcode{T}_i$ x[] =} \tcode{\{std::forward(t)\};} +is well-formed for some invented variable \tcode{x} and, +if $\tcode{T}_i$ is \cv~\tcode{bool}, \tcode{remove_cvref_t} is \tcode{bool}. +The overload \tcode{\placeholdernc{FUN}($\tcode{T}_j$)} selected by overload resolution for the expression \tcode{\placeholdernc{FUN}(std::forward(\brk{}t))} defines the alternative $\tcode{T}_j$ which is the type of the contained value after construction. @@ -3974,7 +4001,7 @@ with \tcode{std::forward(t)}. \pnum -\postconditions +\ensures \tcode{holds_alternative<$\tcode{T}_j$>(*this)} is \tcode{true}. \pnum @@ -4033,7 +4060,7 @@ with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{holds_alternative(*this)} is \tcode{true}. \pnum @@ -4043,7 +4070,7 @@ \pnum \remarks This function shall not participate in overload resolution unless there is -exactly one occurrence of \tcode{T} in \tcode{Types...} and +exactly one occurrence of \tcode{T} in \tcode{Types} and \tcode{is_constructible_v} is \tcode{true}. If \tcode{T}'s selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor. @@ -4063,7 +4090,7 @@ with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{holds_alternative(*this)} is \tcode{true}. \pnum @@ -4073,7 +4100,7 @@ \pnum \remarks This function shall not participate in overload resolution unless there is -exactly one occurrence of \tcode{T} in \tcode{Types...} and +exactly one occurrence of \tcode{T} in \tcode{Types} and \tcode{is_constructible_v\&, Args...>} is \tcode{true}. If \tcode{T}'s selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor. @@ -4092,7 +4119,7 @@ with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{index()} is \tcode{I}. \pnum @@ -4126,7 +4153,7 @@ with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{index()} is \tcode{I}. \pnum @@ -4165,7 +4192,7 @@ \indexlibrarymember{operator=}{variant}% \begin{itemdecl} -variant& operator=(const variant& rhs); +constexpr variant& operator=(const variant& rhs); \end{itemdecl} \begin{itemdescr} @@ -4196,7 +4223,7 @@ \returns \tcode{*this}. \pnum -\postconditions \tcode{index() == rhs.index()}. +\ensures \tcode{index() == rhs.index()}. \pnum \remarks @@ -4204,11 +4231,15 @@ \tcode{is_copy_constructible_v<$\tcode{T}_i$> \&\&} \tcode{is_copy_assignable_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. +If \tcode{is_trivially_copy_constructible_v<$\tcode{T}_i$> \&\&} +\tcode{is_trivially_copy_assignable_v<$\tcode{T}_i$> \&\&} +\tcode{is_trivially_destructible_v<$\tcode{T}_i$>} +is true for all $i$, this assignment operator is trivial. \end{itemdescr} \indexlibrarymember{operator=}{variant}% \begin{itemdecl} -variant& operator=(variant&& rhs) noexcept(@\seebelow@); +constexpr variant& operator=(variant&& rhs) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -4236,13 +4267,18 @@ \pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_move_constructible_v<$\tcode{T}_i$> \&\& is_move_assignable_v<$\tcode{T}_i$>} is +\tcode{is_move_constructible_v<$\tcode{T}_i$> \&\&} +\tcode{is_move_assignable_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. +If \tcode{is_trivially_move_constructible_v<$\tcode{T}_i$> \&\&} +\tcode{is_trivially_move_assignable_v<$\tcode{T}_i$> \&\&} +\tcode{is_trivially_destructible_v<$\tcode{T}_i$>} +is true for all $i$, this assignment operator is trivial. The expression inside \tcode{noexcept} is equivalent to: \tcode{is_nothrow_move_constructible_v<$\tcode{T}_i$> \&\& is_nothrow_move_assignable_v<$\tcode{T}_i$>} for all $i$. \begin{itemize} \item If an exception is thrown during the call to $\tcode{T}_j$'s move construction -(with $j$ being \tcode{rhs.index())}, the \tcode{variant} will hold no value. +(with $j$ being \tcode{rhs.index()}), the \tcode{variant} will hold no value. \item If an exception is thrown during the call to $\tcode{T}_j$'s move assignment, the state of the contained value is as defined by the exception safety guarantee of $\tcode{T}_j$'s move assignment; \tcode{index()} will be $j$. @@ -4257,8 +4293,12 @@ \begin{itemdescr} \pnum Let $\tcode{T}_j$ be a type that is determined as follows: -build an imaginary function \tcode{\placeholdernc{FUN}($\tcode{T}_i$)} for each alternative type -$\tcode{T}_i$. The overload \tcode{\placeholdernc{FUN}($\tcode{T}_j$)} selected by overload +build an imaginary function \tcode{\placeholdernc{FUN}($\tcode{T}_i$)} +for each alternative type $\tcode{T}_i$ +for which \tcode{$\tcode{T}_i$ x[] =} \tcode{\{std::forward(t)\};} +is well-formed for some invented variable \tcode{x} and, +if $\tcode{T}_i$ is \cv~\tcode{bool}, \tcode{remove_cvref_t} is \tcode{bool}. +The overload \tcode{\placeholdernc{FUN}($\tcode{T}_j$)} selected by overload resolution for the expression \tcode{\placeholdernc{FUN}(std::forward(\brk{}t))} defines the alternative $\tcode{T}_j$ which is the type of the contained value after assignment. @@ -4278,7 +4318,7 @@ \end{itemize} \pnum -\postconditions +\ensures \tcode{holds_alternative<$\tcode{T}_j$>(*this)} is \tcode{true}, with $\tcode{T}_j$ selected by the imaginary function overload resolution described above. @@ -4335,7 +4375,7 @@ \begin{itemdescr} \pnum -Let $I$ be the zero-based index of \tcode{T} in \tcode{Types...}. +Let $I$ be the zero-based index of \tcode{T} in \tcode{Types}. \pnum \effects @@ -4345,7 +4385,7 @@ \remarks This function shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true}, and \tcode{T} occurs -exactly once in \tcode{Types...}. +exactly once in \tcode{Types}. \end{itemdescr} \indexlibrarymember{emplace}{variant}% @@ -4355,7 +4395,7 @@ \begin{itemdescr} \pnum -Let $I$ be the zero-based index of \tcode{T} in \tcode{Types...}. +Let $I$ be the zero-based index of \tcode{T} in \tcode{Types}. \pnum \effects @@ -4365,7 +4405,7 @@ \remarks This function shall not participate in overload resolution unless \tcode{is_constructible_v\&, Args...>} is \tcode{true}, -and \tcode{T} occurs exactly once in \tcode{Types...}. +and \tcode{T} occurs exactly once in \tcode{Types}. \end{itemdescr} \indexlibrarymember{emplace}{variant}% @@ -4388,7 +4428,7 @@ with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{index()} is \tcode{I}. \pnum @@ -4427,7 +4467,7 @@ with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions +\ensures \tcode{index()} is \tcode{I}. \pnum @@ -4525,7 +4565,7 @@ If an exception is thrown during the exchange of the values of \tcode{*this} and \tcode{rhs}, the states of the values of \tcode{*this} and of \tcode{rhs} are determined by the exception safety guarantee of \tcode{variant}'s move constructor. -The expression inside \tcode{noexcept} is equivalent to the logical AND of +The expression inside \tcode{noexcept} is equivalent to the logical \logop{AND} of \tcode{is_nothrow_move_constructible_v<$\tcode{T}_i$> \&\& is_nothrow_swappable_v<$\tcode{T}_i$>} for all $i$. \end{itemdescr} @@ -4612,12 +4652,12 @@ \begin{itemdescr} \pnum \requires -The type \tcode{T} occurs exactly once in \tcode{Types...}. +The type \tcode{T} occurs exactly once in \tcode{Types}. Otherwise, the program is ill-formed. \pnum \returns -\tcode{true} if \tcode{index()} is equal to the zero-based index of \tcode{T} in \tcode{Types...}. +\tcode{true} if \tcode{index()} is equal to the zero-based index of \tcode{T} in \tcode{Types}. \end{itemdescr} \indexlibrarymember{get}{variant}% @@ -4655,7 +4695,7 @@ \begin{itemdescr} \pnum \requires -The type \tcode{T} occurs exactly once in \tcode{Types...}. +The type \tcode{T} occurs exactly once in \tcode{Types}. Otherwise, the program is ill-formed. \pnum @@ -4701,13 +4741,13 @@ \begin{itemdescr} \pnum \requires -The type \tcode{T} occurs exactly once in \tcode{Types...}. +The type \tcode{T} occurs exactly once in \tcode{Types}. Otherwise, the program is ill-formed. \pnum \effects Equivalent to: \tcode{return get_if<$i$>(v);} with $i$ being the zero-based -index of \tcode{T} in \tcode{Types...}. +index of \tcode{T} in \tcode{Types}. \end{itemdescr} \rSec2[variant.relops]{Relational operators} @@ -4841,6 +4881,8 @@ \begin{itemdecl} template constexpr @\seebelow@ visit(Visitor&& vis, Variants&&... vars); +template + constexpr R visit(Visitor&& vis, Variants&&... vars); \end{itemdecl} \begin{itemdescr} @@ -4853,6 +4895,11 @@ \begin{codeblock} @\placeholder{INVOKE}@(std::forward(vis), get(std::forward(vars))...) // see \ref{func.require} \end{codeblock} +for the first form and +\begin{codeblock} +@\placeholder{INVOKE}@(std::forward(vis), get(std::forward(vars))...) // see \ref{func.require} +\end{codeblock} +for the second form. \pnum \requires @@ -4862,8 +4909,9 @@ \pnum \returns $e(\tcode{m})$, where \tcode{m} is the pack for which -$\tcode{m}_i$ is \tcode{vars$_i$.index()} for -all $0 \leq i < n$. The return type is $\tcode{decltype(}e(\tcode{m})\tcode{)}$. +$\tcode{m}_i$ is \tcode{vars$_i$.index()} for all $0 \leq i < n$. +The return type is $\tcode{decltype(}e(\tcode{m})\tcode{)}$ +for the first form. \pnum \throws @@ -5139,7 +5187,7 @@ \begin{itemdescr} \pnum -\postconditions +\ensures \tcode{has_value()} is \tcode{false}. \end{itemdescr} @@ -5175,7 +5223,7 @@ the contained value of \tcode{other} considering that contained value as an rvalue. \pnum -\postconditions +\ensures \tcode{other} is left in a valid but otherwise unspecified state. \end{itemdescr} @@ -5227,7 +5275,7 @@ type \tcode{VT} with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions \tcode{*this} contains a value of type \tcode{VT}. +\ensures \tcode{*this} contains a value of type \tcode{VT}. \pnum \throws Any exception thrown by the selected constructor of \tcode{VT}. @@ -5257,7 +5305,7 @@ type \tcode{VT} with the arguments \tcode{il, std::forward(args)...}. \pnum -\postconditions \tcode{*this} contains a value. +\ensures \tcode{*this} contains a value. \pnum \throws Any exception thrown by the selected constructor of \tcode{VT}. @@ -5317,7 +5365,7 @@ \tcode{*this}. \pnum -\postconditions +\ensures The state of \tcode{*this} is equivalent to the original state of \tcode{rhs} and \tcode{rhs} is left in a valid but otherwise unspecified state. \end{itemdescr} @@ -5378,7 +5426,7 @@ an object of type \tcode{VT} with the arguments \tcode{std::forward(args)...}. \pnum -\postconditions \tcode{*this} contains a value. +\ensures \tcode{*this} contains a value. \pnum \returns @@ -5416,7 +5464,7 @@ \tcode{il, std::forward(args)...}. \pnum -\postconditions \tcode{*this} contains a value. +\ensures \tcode{*this} contains a value. \pnum \returns @@ -5445,7 +5493,7 @@ If \tcode{has_value()} is \tcode{true}, destroys the contained value. \pnum -\postconditions +\ensures \tcode{has_value()} is \tcode{false}. \end{itemdescr} @@ -5782,7 +5830,7 @@ \indexlibrary{\idxcode{overflow_error}}% \end{itemize} -\rSec3[bitset.cons]{\tcode{bitset} constructors} +\rSec3[bitset.cons]{Constructors} \indexlibrary{\idxcode{bitset}!constructor}% \begin{itemdecl} @@ -5892,7 +5940,7 @@ \end{itemdescr} -\rSec3[bitset.members]{\tcode{bitset} members} +\rSec3[bitset.members]{Members} \indexlibrarymember{operator\&=}{bitset}% \begin{itemdecl} @@ -6524,8 +6572,10 @@ void undeclare_no_pointers(char* p, size_t n); pointer_safety get_pointer_safety() noexcept; - // \ref{ptr.align}, pointer alignment function + // \ref{ptr.align}, pointer alignment void* align(size_t alignment, size_t size, void*& ptr, size_t& space); + template + [[nodiscard]] constexpr T* assume_aligned(T* ptr); // \ref{allocator.tag}, allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; @@ -6534,6 +6584,29 @@ // \ref{allocator.uses}, \tcode{uses_allocator} template struct uses_allocator; + // \ref{allocator.uses.trait}, \tcode{uses_allocator} + template + inline constexpr bool uses_allocator_v = uses_allocator::value; + + // \ref{allocator.uses.construction}, uses-allocator construction + template + auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> @\seebelow@; + template + auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, + Tuple1&& x, Tuple2&& y) -> @\seebelow@; + template + auto uses_allocator_construction_args(const Alloc& alloc) -> @\seebelow@; + template + auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) -> @\seebelow@; + template + auto uses_allocator_construction_args(const Alloc& alloc, const pair& pr) -> @\seebelow@; + template + auto uses_allocator_construction_args(const Alloc& alloc, pair&& pr) -> @\seebelow@; + template + T make_obj_using_allocator(const Alloc& alloc, Args&&... args); + template + T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); + // \ref{allocator.traits}, allocator traits template struct allocator_traits; @@ -6545,6 +6618,18 @@ bool operator!=(const allocator&, const allocator&) noexcept; // \ref{specialized.algorithms}, specialized algorithms + // \ref{special.mem.concepts}, special memory concepts + template + concept @\placeholdernc{no-throw-input-iterator}@ = @\seebelow@; // \expos + template + concept @\placeholdernc{no-throw-forward-iterator}@ = @\seebelow@; // \expos + template + concept @\placeholdernc{no-throw-sentinel}@ = @\seebelow@; // \expos + template + concept @\placeholdernc{no-throw-input-range}@ = @\seebelow@; // \expos + template + concept @\placeholdernc{no-throw-forward-range}@ = @\seebelow@; // \expos + template constexpr T* addressof(T& r) noexcept; template @@ -6559,6 +6644,20 @@ template ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); + + namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires DefaultConstructible> + I uninitialized_default_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires DefaultConstructible>> + safe_iterator_t uninitialized_default_construct(R&& r); + + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires DefaultConstructible> + I uninitialized_default_construct_n(I first, iter_difference_t n); + } + template void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); template @@ -6569,6 +6668,20 @@ template ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); + + namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires DefaultConstructible> + I uninitialized_value_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires DefaultConstructible>> + safe_iterator_t uninitialized_value_construct(R&& r); + + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires DefaultConstructible> + I uninitialized_value_construct_n(I first, iter_difference_t n); + } + template ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); @@ -6583,6 +6696,28 @@ ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, Size n, ForwardIterator result); + + namespace ranges { + template + using uninitialized_copy_result = copy_result; + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires Constructible, iter_reference_t> + uninitialized_copy_result + uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires Constructible>, iter_reference_t>> + uninitialized_copy_result, safe_iterator_t> + uninitialized_copy(IR&& input_range, OR&& output_range); + + template + using uninitialized_copy_n_result = uninitialized_copy_result; + template S> + requires Constructible, iter_reference_t> + uninitialized_copy_n_result + uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); + } + template ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); @@ -6597,6 +6732,30 @@ pair uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, Size n, ForwardIterator result); + + namespace ranges { + template + using uninitialized_move_result = uninitialized_copy_result; + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires Constructible, iter_rvalue_reference_t> + uninitialized_move_result + uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires Constructible>, + iter_rvalue_reference_t>> + uninitialized_move_result, safe_iterator_t> + uninitialized_move(IR&& input_range, OR&& output_range); + + template + using uninitialized_move_n_result = uninitialized_copy_result; + template S> + requires Constructible, iter_rvalue_reference_t> + uninitialized_move_n_result + uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); + } + template void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); template @@ -6607,6 +6766,20 @@ template ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, const T& x); + + namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S, class T> + requires Constructible, const T&> + I uninitialized_fill(I first, S last, const T& x); + template<@\placeholdernc{no-throw-forward-range}@ R, class T> + requires Constructible>, const T&> + safe_iterator_t uninitialized_fill(R&& r, const T& x); + + template<@\placeholdernc{no-throw-forward-iterator}@ I, class T> + requires Constructible, const T&> + I uninitialized_fill_n(I first, iter_difference_t n, const T& x); + } + template void destroy_at(T* location); template @@ -6620,19 +6793,42 @@ ForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); + namespace ranges { + template + void destroy_at(T* location) noexcept; + + template<@\placeholdernc{no-throw-input-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires Destructible> + I destroy(I first, S last) noexcept; + template<@\placeholdernc{no-throw-input-range}@ R> + requires Destructible> + safe_iterator_t destroy(R&& r) noexcept; + + template<@\placeholdernc{no-throw-input-iterator}@ I> + requires Destructible> + I destroy_n(I first, iter_difference_t n) noexcept; + } + // \ref{unique.ptr}, class template \tcode{unique_ptr} template struct default_delete; template struct default_delete; template> class unique_ptr; template class unique_ptr; - template unique_ptr - make_unique(Args&&... args); // \tcode{T} is not array - template unique_ptr - make_unique(size_t n); // \tcode{T} is \tcode{U[]} + template + unique_ptr make_unique(Args&&... args); // \tcode{T} is not array + template + unique_ptr make_unique(size_t n); // \tcode{T} is \tcode{U[]} template @\unspecnc@ make_unique(Args&&...) = delete; // \tcode{T} is \tcode{U[N]} + template + unique_ptr make_unique_default_init(); // \tcode{T} is not array + template + unique_ptr make_unique_default_init(size_t n); // \tcode{T} is \tcode{U[]} + template + @\unspecnc@ make_unique_default_init(Args&&...) = delete; // \tcode{T} is \tcode{U[N]} + template void swap(unique_ptr& x, unique_ptr& y) noexcept; @@ -6705,11 +6901,21 @@ shared_ptr allocate_shared(const A& a, size_t N, const remove_extent_t& u); // \tcode{T} is \tcode{U[]} - template shared_ptr - make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + template + shared_ptr make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} template shared_ptr allocate_shared(const A& a, const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + template + shared_ptr make_shared_default_init(); // \tcode{T} is not \tcode{U[]} + template + shared_ptr allocate_shared_default_init(const A& a); // \tcode{T} is not \tcode{U[]} + + template + shared_ptr make_shared_default_init(size_t N); // \tcode{T} is \tcode{U[]} + template + shared_ptr allocate_shared_default_init(const A& a, size_t N); // \tcode{T} is \tcode{U[]} + // \ref{util.smartptr.shared.cmp}, \tcode{shared_ptr} comparisons template bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; @@ -6756,12 +6962,20 @@ // \ref{util.smartptr.shared.cast}, \tcode{shared_ptr} casts template shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; + template + shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; template shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; + template + shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; template shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; + template + shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; template shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; + template + shared_ptr reinterpret_pointer_cast(shared_ptr&& r) noexcept; // \ref{util.smartptr.getdeleter}, \tcode{shared_ptr} \tcode{get_deleter} template @@ -6791,10 +7005,6 @@ // \ref{util.smartptr.atomic}, atomic smart pointers template struct atomic>; template struct atomic>; - - // \ref{allocator.uses.trait}, \tcode{uses_allocator} - template - inline constexpr bool uses_allocator_v = uses_allocator::value; } \end{codeblock} @@ -6824,12 +7034,12 @@ template using rebind = U*; - static pointer pointer_to(@\seebelow@ r) noexcept; + static constexpr pointer pointer_to(@\seebelow@ r) noexcept; }; } \end{codeblock} -\rSec3[pointer.traits.types]{Pointer traits member types} +\rSec3[pointer.traits.types]{Member types} \indexlibrarymember{element_type}{pointer_traits}% \begin{itemdecl} @@ -6875,12 +7085,12 @@ \tcode{rebind} is ill-formed. \end{itemdescr} -\rSec3[pointer.traits.functions]{Pointer traits member functions} +\rSec3[pointer.traits.functions]{Member functions} \indexlibrarymember{pointer_to}{pointer_traits}% \begin{itemdecl} static pointer pointer_traits::pointer_to(@\seebelow@ r); -static pointer pointer_traits::pointer_to(@\seebelow@ r) noexcept; +static constexpr pointer pointer_traits::pointer_to(@\seebelow@ r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6896,7 +7106,7 @@ function. The second member function returns \tcode{addressof(r)}. \end{itemdescr} -\rSec3[pointer.traits.optmem]{Pointer traits optional members} +\rSec3[pointer.traits.optmem]{Optional members} \pnum Specializations of \tcode{pointer_traits} may define the member declared @@ -7072,7 +7282,7 @@ \end{itemdescr} -\rSec2[ptr.align]{Align} +\rSec2[ptr.align]{Pointer alignment} \indexlibrary{\idxcode{align}}% \begin{itemdecl} @@ -7110,6 +7320,44 @@ arguments for the same buffer. \end{note} \end{itemdescr} +\indexlibrary{\idxcode{assume_aligned}}% +\begin{itemdecl} +template + [[nodiscard]] constexpr T* assume_aligned(T* ptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{N} is a power of two. + +\pnum +\expects +\tcode{ptr} points to an object \tcode{X} of +a type similar\iref{conv.qual} to \tcode{T}, +where \tcode{X} has alignment \tcode{N}\iref{basic.align}. + +\pnum +\returns +\tcode{ptr}. + +\pnum +\throws +Nothing. + +\pnum +\begin{note} +The alignment assumption on an object \tcode{X} +expressed by a call to \tcode{assume_aligned} +may result in generation of more efficient code. +It is up to the program to ensure that the assumption actually holds. +The call does not cause the compiler to verify or enforce this. +An implementation might only make the assumption +for those operations on \tcode{X} that access \tcode{X} +through the pointer returned by \tcode{assume_aligned}. +\end{note} +\end{itemdescr} + \rSec2[allocator.tag]{Allocator argument tag} \indexlibrary{\idxcode{allocator_arg_t}}% @@ -7161,30 +7409,236 @@ \rSec3[allocator.uses.construction]{Uses-allocator construction} \pnum -\defnx{Uses-allocator construction}{uses-allocator construction} with allocator \tcode{Alloc} refers to the -construction of an object \tcode{obj} of type \tcode{T}, using constructor arguments -\tcode{v1, v2, ..., vN} of types \tcode{V1, V2, ..., VN}, respectively, and an allocator -\tcode{alloc} of type \tcode{Alloc}, according to the following rules: +\defnx{Uses-allocator construction}{uses-allocator construction} +with allocator \tcode{alloc} and constructor arguments \tcode{args...} +refers to the construction of an object of type \tcode{T} +such that \tcode{alloc} is passed to the constructor of \tcode{T} +if \tcode{T} uses an allocator type compatible with \tcode{alloc}. +When applied to the construction of an object of type \tcode{T}, +it is equivalent to initializing it with the value of the expression +\tcode{make_obj_using_allocator(alloc, args...)}, described below. + +\pnum +The following utility functions support +three conventions for passing \tcode{alloc} to a constructor: +\begin{itemize} +\item + If \tcode{T} does not use an allocator compatible with \tcode{alloc}, + then \tcode{alloc} is ignored. +\item + Otherwise, if \tcode{T} has a constructor invocable as + \tcode{T(allocator_arg, alloc, args...)} (leading-allocator convention), + then uses-allocator construction chooses this constructor form. +\item + Otherwise, if \tcode{T} has a constructor invocable as + \tcode{T(args..., alloc)} (trailing-allocator convention), + then uses-allocator construction chooses this constructor form. +\end{itemize} + +\pnum +The \tcode{uses_allocator_construction_args} function template +takes an allocator and argument list and +produces (as a tuple) a new argument list matching one of the above conventions. +Additionally, overloads are provided +that treat specializations of \tcode{pair} +such that uses-allocator construction is applied individually +to the \tcode{first} and \tcode{second} data members. +The \tcode{make_obj_using_allocator} and +\tcode{uninitialized_construct_using_allocator} function templates +apply the modified constructor arguments +to construct an object of type \tcode{T} +as a return value or in-place, respectively. +\begin{note} +For \tcode{uses_allocator_construction_args} and +\tcode{make_obj_using_allocator}, type \tcode{T} +is not deduced and must therefore be specified explicitly by the caller. +\end{note} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is not a specialization of \tcode{pair}. +\pnum +\returns +A \tcode{tuple} value determined as follows: \begin{itemize} -\item if \tcode{uses_allocator_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}, then \tcode{obj} is -initialized as \tcode{obj(v1, v2, ..., vN)}; - -\item otherwise, if \tcode{uses_allocator_v} is \tcode{true} and -\tcode{is_constructible_v} is -\tcode{true}, then \tcode{obj} is initialized as \tcode{obj(allocator_arg, alloc, v1, -v2, ..., vN)}; - -\item otherwise, if \tcode{uses_allocator_v} is \tcode{true} and -\tcode{is_constructible_v} is \tcode{true}, then -\tcode{obj} is initialized as \tcode{obj(v1, v2, ..., vN, alloc)}; - -\item otherwise, the request for uses-allocator construction is ill-formed. \begin{note} -An error will result if \tcode{uses_allocator_v} is \tcode{true} but the -specific constructor does not take an allocator. This definition prevents a silent -failure to pass the allocator to an element. \end{note} +\item + If \tcode{uses_allocator_v} is \tcode{false} and + \tcode{is_constructible_v} is \tcode{true}, + return \tcode{forward_as_tuple(std::forward(args)...)}. +\item + Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and + \tcode{is_constructible_v} + is \tcode{true}, + return +\begin{codeblock} +tuple( + allocator_arg, alloc, std::forward(args)...) +\end{codeblock} +\item + Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and + \tcode{is_constructible_v} is \tcode{true}, + return \tcode{forward_as_tuple(std::forward(args)..., alloc)}. +\item + Otherwise, the program is ill-formed. \end{itemize} +\begin{note} +This definition prevents a silent failure +to pass the allocator to a constructor of a type for which +\tcode{uses_allocator_v} is \tcode{true}. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, + Tuple1&& x, Tuple2&& y) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a specialization of \tcode{pair}. + +\pnum +\effects +For \tcode{T} specified as \tcode{pair}, equivalent to: +\begin{codeblock} +return make_tuple( + piecewise_construct, + apply([&alloc](auto&&... args1) { + return uses_allocator_construction_args( + alloc, std::forward(args1)...); + }, std::forward(x)), + apply([&alloc](auto&&... args2) { + return uses_allocator_construction_args( + alloc, std::forward(args2)...); + }, std::forward(y))); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a specialization of \tcode{pair}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uses_allocator_construction_args(alloc, piecewise_construct, + tuple<>{}, tuple<>{}); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a specialization of \tcode{pair}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uses_allocator_construction_args(alloc, piecewise_construct, + forward_as_tuple(std::forward(u)), + forward_as_tuple(std::forward(v))); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc, const pair& pr) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a specialization of \tcode{pair}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uses_allocator_construction_args(alloc, piecewise_construct, + forward_as_tuple(pr.first), + forward_as_tuple(pr.second)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uses_allocator_construction_args}}% +\begin{itemdecl} +template + auto uses_allocator_construction_args(const Alloc& alloc, pair&& pr) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a specialization of \tcode{pair}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uses_allocator_construction_args(alloc, piecewise_construct, + forward_as_tuple(std::move(pr).first), + forward_as_tuple(std::move(pr).second)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{make_obj_using_allocator}}% +\begin{itemdecl} +template + T make_obj_using_allocator(const Alloc& alloc, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return make_from_tuple(uses_allocator_construction_args( + alloc, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uninitialized_construct_using_allocator}}% +\begin{itemdecl} +template + T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ::new(static_cast(p)) + T(make_obj_using_allocator(alloc, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} \rSec2[allocator.traits]{Allocator traits} @@ -7237,7 +7691,7 @@ } \end{codeblock} -\rSec3[allocator.traits.types]{Allocator traits member types} +\rSec3[allocator.traits.types]{Member types} \indexlibrarymember{pointer}{allocator_traits}% \begin{itemdecl} @@ -7383,7 +7837,7 @@ otherwise, the instantiation of \tcode{rebind_alloc} is ill-formed. \end{itemdescr} -\rSec3[allocator.traits.members]{Allocator traits static member functions} +\rSec3[allocator.traits.members]{Static member functions} \indexlibrarymember{allocate}{allocator_traits}% \begin{itemdecl} @@ -7500,7 +7954,7 @@ } \end{codeblock} -\rSec3[allocator.members]{\tcode{allocator} members} +\rSec3[allocator.members]{Members} \pnum Except for the destructor, member functions of the default allocator shall not introduce @@ -7555,7 +8009,7 @@ when this function is called. \end{itemdescr} -\rSec3[allocator.globals]{\tcode{allocator} globals} +\rSec3[allocator.globals]{Operators} \indexlibrarymember{operator==}{allocator}% \begin{itemdecl} @@ -7585,21 +8039,157 @@ \pnum Throughout this subclause, -the names of template parameters are used to express type requirements. +the names of template parameters are used to express type requirements +for those algorithms defined directly in namespace \tcode{std}. \begin{itemize} \item If an algorithm's template parameter is named \tcode{InputIterator}, -the template argument shall satisfy the +the template argument shall meet the \oldconcept{InputIterator} requirements\iref{input.iterators}. \item If an algorithm's template parameter is named \tcode{ForwardIterator}, -the template argument shall satisfy the +the template argument shall meet the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators. \end{itemize} + +\pnum Unless otherwise specified, -if an exception is thrown in the following algorithms there are no effects. +if an exception is thrown in the following algorithms, +objects constructed by a placement \grammarterm{new-expression}\iref{expr.new} +are destroyed in an unspecified order +before allowing the exception to propagate. + +\pnum +In the description of the algorithms, operator \tcode{-} +is used for some of the iterator categories for which +it need not be defined. +In these cases, the value of the expression \tcode{b - a} +is the number of increments of \tcode{a} needed to make +\tcode{bool(a == b)} be \tcode{true}. + +\pnum +The following additional requirements apply for those algorithms +defined in namespace \tcode{std::ranges}: +\begin{itemize} +\item The entities defined in the \tcode{std::ranges} namespace + in this subclause are not found by argument-dependent + name lookup\iref{basic.lookup.argdep}. When found by + unqualified\iref{basic.lookup.unqual} name lookup for the + \grammarterm{postfix-expression} in a function call\iref{expr.call}, they + inhibit argument-dependent name lookup. +\item Overloads of algorithms that take \libconcept{Range} arguments\iref{range.range} + behave as if they are implemented by calling \tcode{ranges::begin} + and \tcode{ranges::end} on the \libconcept{Range}(s) and dispatching to the + overload that takes separate iterator and sentinel arguments. +\item The number and order of deducible template parameters for algorithm declarations + is unspecified, except where explicitly stated otherwise. + \begin{note} + Consequently, these algorithms may not be called with + explicitly-specified template argument lists. + \end{note} +\end{itemize} + +\pnum +\begin{note} +When invoked on ranges of +potentially overlapping subobjects\iref{intro.object}, +the algorithms specified in this subclause \ref{specialized.algorithms} +result in undefined behavior. +\end{note} + +\pnum +Some algorithms defined in this clause make use of the exposition-only function +\tcode{\placeholdernc{voidify}}: +\begin{codeblock} +template + void* @\placeholdernc{voidify}@(T& ptr) noexcept { + return const_cast(static_cast(addressof(ptr))); + } +\end{codeblock} + +\rSec3[special.mem.concepts]{Special memory concepts} + +\pnum +Some algorithms in this subclause are constrained with the following +exposition-only concepts: + +\begin{itemdecl} +template +concept @\placeholdernc{no-throw-input-iterator}@ = // exposition only + InputIterator && + is_lvalue_reference_v> && + Same>, iter_value_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +No exceptions are thrown from increment, +copy construction, move construction, +copy assignment, move assignment, +or indirection through valid iterators. + +\pnum +\begin{note} +This concept allows some \tcode{InputIterator}\iref{iterator.concept.input} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\placeholdernc{no-throw-sentinel}@ = Sentinel; // exposition only +\end{itemdecl} + +\begin{itemdescr} +\pnum +No exceptions are thrown from copy construction, move construction, +copy assignment, move assignment, or comparisons between +valid values of type \tcode{I} and \tcode{S}. + +\pnum +\begin{note} +This concept allows some \tcode{Sentinel}\iref{iterator.concept.sentinel} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\placeholdernc{no-throw-input-range}@ = // exposition only + Range && + @\placeholder{no-throw-input-iterator}@> && + @\placeholdernc{no-throw-sentinel}@, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum No exceptions are thrown from calls to \tcode{ranges::begin} and +\tcode{ranges::end} on an object of type \tcode{R}. +\end{itemdescr} + +\begin{itemdecl} +template +concept @\placeholdernc{no-throw-forward-iterator}@ = // exposition only + @\placeholder{no-throw-input-iterator}@ && + ForwardIterator && + @\placeholdernc{no-throw-sentinel}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +This concept allows some \tcode{ForwardIterator}\iref{iterator.concept.forward} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\placeholdernc{no-throw-forward-range}@ = // exposition only + @\placeholder{no-throw-input-range}@ && + @\placeholder{no-throw-forward-iterator}@>; +\end{itemdecl} \rSec3[specialized.addressof]{\tcode{addressof}} @@ -7633,12 +8223,34 @@ Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type; \end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{uninitialized_default_construct_n}}% +\indexlibrary{\idxcode{uninitialized_default_construct}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires DefaultConstructible> + I uninitialized_default_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires DefaultConstructible>> + safe_iterator_t uninitialized_default_construct(R&& r); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>; +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uninitialized_default_construct_n}}% \begin{itemdecl} template ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); @@ -7650,12 +8262,30 @@ Equivalent to: \begin{codeblock} for (; n > 0; (void)++first, --n) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type; return first; \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_default_construct_n}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires DefaultConstructible> + I uninitialized_default_construct_n(I first, iter_difference_t n); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return uninitialized_default_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + \rSec3[uninitialized.construct.value]{\tcode{uninitialized_value_construct}} \indexlibrary{\idxcode{uninitialized_value_construct}}% @@ -7670,11 +8300,33 @@ Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type(); \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_value_construct}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires DefaultConstructible> + I uninitialized_value_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires DefaultConstructible>> + safe_iterator_t uninitialized_value_construct(R&& r); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(); +return first; +\end{codeblock} +\end{itemdescr} + \indexlibrary{\idxcode{uninitialized_value_construct_n}}% \begin{itemdecl} template @@ -7687,12 +8339,30 @@ Equivalent to: \begin{codeblock} for (; n > 0; (void)++first, --n) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type(); return first; \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_value_construct_n}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires DefaultConstructible> + I uninitialized_value_construct_n(I first, iter_difference_t n); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return uninitialized_value_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + \rSec3[uninitialized.copy]{\tcode{uninitialized_copy}} \indexlibrary{\idxcode{uninitialized_copy}}% @@ -7703,12 +8373,16 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\range{result}{(last - first)} shall not overlap with \range{first}{last}. + \pnum \effects -As if by: +Equivalent to: \begin{codeblock} for (; first != last; ++result, (void) ++first) - ::new (static_cast(addressof(*result))) + ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(*first); \end{codeblock} @@ -7717,6 +8391,36 @@ \tcode{result}. \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_copy}}% +\begin{itemdecl} +namespace ranges { + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires Constructible, iter_reference_t> + uninitialized_copy_result + uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires Constructible>, iter_reference_t>> + uninitialized_copy_result, safe_iterator_t> + uninitialized_copy(IR&& input_range, OR&& output_range); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} shall not overlap with \range{ifirst}{ilast}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { + ::new (@\placeholdernc{voidify}@(*ofirst)) remove_reference_t>(*ifirst); +} +return {ifirst, ofirst}; +\end{codeblock} +\end{itemdescr} + \indexlibrary{\idxcode{uninitialized_copy_n}}% \begin{itemdecl} template @@ -7724,12 +8428,16 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\range{result}{n} shall not overlap with \range{first}{n}. + \pnum \effects -As if by: +Equivalent to: \begin{codeblock} for ( ; n > 0; ++result, (void) ++first, --n) { - ::new (static_cast(addressof(*result))) + ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(*first); } \end{codeblock} @@ -7738,6 +8446,31 @@ \returns \tcode{result}. \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_copy_n}}% +\begin{itemdecl} +namespace ranges { + template S> + requires Constructible, iter_reference_t> + uninitialized_copy_n_result + uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} shall not overlap with +\range{ifirst}{n}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +auto t = uninitialized_copy(counted_iterator(ifirst, n), + default_sentinel, ofirst, olast); +return {t.in.base(), t.out}; +\end{codeblock} +\end{itemdescr} + \rSec3[uninitialized.move]{\tcode{uninitialized_move}} \indexlibrary{\idxcode{uninitialized_move}}% @@ -7748,20 +8481,56 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\range{result}{(last - first)} shall not overlap with \range{first}{last}. + \pnum \effects Equivalent to: \begin{codeblock} for (; first != last; (void)++result, ++first) - ::new (static_cast(addressof(*result))) + ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(std::move(*first)); return result; \end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uninitialized_move}}% +\begin{itemdecl} +namespace ranges { + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires Constructible, iter_rvalue_reference_t> + uninitialized_move_result + uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires Constructible>, iter_rvalue_reference_t>> + uninitialized_move_result, safe_iterator_t> + uninitialized_move(IR&& input_range, OR&& output_range); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\remarks -If an exception is thrown, some objects in the range \range{first}{last} -are left in a valid but unspecified state. +\expects +\range{ofirst}{olast} shall not overlap with \range{ifirst}{ilast}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { + ::new (@\placeholder{voidify}@(*ofirst)) + remove_reference_t>(ranges::iter_move(ifirst)); +} +return {ifirst, ofirst}; +\end{codeblock} + +\pnum +\begin{note} +If an exception is thrown, some objects in the range \range{first}{last} are +left in a valid, but unspecified state. +\end{note} \end{itemdescr} \indexlibrary{\idxcode{uninitialized_move_n}}% @@ -7772,20 +8541,51 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\range{result}{n} shall not overlap with \range{first}{n}. + \pnum \effects Equivalent to: \begin{codeblock} for (; n > 0; ++result, (void) ++first, --n) - ::new (static_cast(addressof(*result))) + ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(std::move(*first)); return {first,result}; \end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{uninitialized_move_n}}% +\begin{itemdecl} +namespace ranges { + template S> + requires Constructible, iter_rvalue_reference_t> + uninitialized_move_n_result + uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} shall not overlap with +\range{ifirst}{n}. + +\pnum +\effects Equivalent to: +\begin{codeblock} +auto t = uninitialized_move(counted_iterator(ifirst, n), + default_sentinel, ofirst, olast); +return {t.in.base(), t.out}; +\end{codeblock} \pnum -\remarks -If an exception is thrown, some objects in the range \range{first}{std::next(first,n)} +\begin{note} +If an exception is thrown, some objects in the range +\range{first}{n} are left in a valid but unspecified state. +\end{note} \end{itemdescr} \rSec3[uninitialized.fill]{\tcode{uninitialized_fill}} @@ -7799,14 +8599,36 @@ \begin{itemdescr} \pnum \effects -As if by: +Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type(x); \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_fill}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S, class T> + requires Constructible, const T&> + I uninitialized_fill(I first, S last, const T& x); + template<@\placeholdernc{no-throw-forward-range}@ R, class T> + requires Constructible>, const T&> + safe_iterator_t uninitialized_fill(R&& r, const T& x); +} +\end{itemdecl} + +\begin{itemdescr} +\effects Equivalent to: +\begin{codeblock} +for (; first != last; ++first) { + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(x); +} +return first; +\end{codeblock} +\end{itemdescr} + \indexlibrary{\idxcode{uninitialized_fill_n}}% \begin{itemdecl} template @@ -7816,30 +8638,53 @@ \begin{itemdescr} \pnum \effects -As if by: +Equivalent to: \begin{codeblock} for (; n--; ++first) - ::new (static_cast(addressof(*first))) + ::new (@\placeholdernc{voidify}@(*first)) typename iterator_traits::value_type(x); return first; \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{uninitialized_fill_n}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, class T> + requires Constructible, const T&> + I uninitialized_fill_n(I first, iter_difference_t n, const T& x); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return uninitialized_fill(counted_iterator(first, n), default_sentinel, x).base(); +\end{codeblock} +\end{itemdescr} + \rSec3[specialized.destroy]{\tcode{destroy}} \indexlibrary{\idxcode{destroy_at}}% \begin{itemdecl} template void destroy_at(T* location); +namespace ranges { + template + void destroy_at(T* location) noexcept; +} \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: -\begin{codeblock} -location->~T(); -\end{codeblock} +\begin{itemize} +\item If \tcode{T} is an array type, equivalent to + \tcode{destroy(begin(*location), end(*location))}. +\item Otherwise, equivalent to + \tcode{location->\~T()}. +\end{itemize} \end{itemdescr} \indexlibrary{\idxcode{destroy}}% @@ -7858,6 +8703,28 @@ \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{destroy}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-input-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires Destructible> + I destroy(I first, S last) noexcept; + template<@\placeholdernc{no-throw-input-range}@ R> + requires Destructible>> + safe_iterator_t destroy(R&& r) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + destroy_at(addressof(*first)); +return first; +\end{codeblock} +\end{itemdescr} + \indexlibrary{\idxcode{destroy_n}}% \begin{itemdecl} template @@ -7875,6 +8742,23 @@ \end{codeblock} \end{itemdescr} +\indexlibrary{\idxcode{destroy_n}}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-input-iterator}@ I> + requires Destructible> + I destroy_n(I first, iter_difference_t n) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return destroy(counted_iterator(first, n), default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + \rSec2[c.malloc]{C library memory allocation} \pnum @@ -8176,7 +9060,7 @@ nothing, value-initializing the stored pointer and the stored deleter. \pnum -\postconditions \tcode{get() == nullptr}. \tcode{get_deleter()} +\ensures \tcode{get() == nullptr}. \tcode{get_deleter()} returns a reference to the stored deleter. \pnum @@ -8202,7 +9086,7 @@ value-initializing the stored deleter. \pnum -\postconditions \tcode{get() == p}. \tcode{get_deleter()} +\ensures \tcode{get() == p}. \tcode{get_deleter()} returns a reference to the stored deleter. \pnum @@ -8241,7 +9125,7 @@ unless \tcode{is_constructible_v} is \tcode{true}. \pnum -\postconditions \tcode{get() == p}. +\ensures \tcode{get() == p}. \tcode{get_deleter()} returns a reference to the stored deleter. If \tcode{D} is a reference type then \tcode{get_deleter()} returns a reference to the lvalue \tcode{d}. @@ -8286,7 +9170,7 @@ construction of the deleter can be implemented with \tcode{std::forward}. \end{note} \pnum -\postconditions \tcode{get()} yields the value \tcode{u.get()} +\ensures \tcode{get()} yields the value \tcode{u.get()} yielded before the construction. \tcode{u.get() == nullptr}. \tcode{get_deleter()} returns a reference to the stored deleter that was constructed from @@ -8326,7 +9210,7 @@ \tcode{std::forward}. \end{note} \pnum -\postconditions \tcode{get()} yields the value \tcode{u.get()} +\ensures \tcode{get()} yields the value \tcode{u.get()} yielded before the construction. \tcode{u.get() == nullptr}. \tcode{get_deleter()} returns a reference to the stored deleter that was constructed from @@ -8377,7 +9261,7 @@ \returns \tcode{*this}. \pnum -\postconditions \tcode{u.get() == nullptr}. +\ensures \tcode{u.get() == nullptr}. \end{itemdescr} \indexlibrarymember{operator=}{unique_ptr}% @@ -8409,7 +9293,7 @@ \returns \tcode{*this}. \pnum -\postconditions \tcode{u.get() == nullptr}. +\ensures \tcode{u.get() == nullptr}. \end{itemdescr} \indexlibrarymember{operator=}{unique_ptr}% @@ -8422,7 +9306,7 @@ \effects As if by \tcode{reset()}. \pnum -\postconditions \tcode{get() == nullptr}. +\ensures \tcode{get() == nullptr}. \pnum \returns \tcode{*this}. @@ -8502,7 +9386,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{get() == nullptr}. +\ensures \tcode{get() == nullptr}. \pnum \returns The value \tcode{get()} had at the start of @@ -8526,7 +9410,7 @@ because the call to \tcode{get_deleter()} may destroy \tcode{*this}. \end{note} \pnum -\postconditions \tcode{get() == p}. +\ensures \tcode{get() == p}. \begin{note} The postcondition does not hold if the call to \tcode{get_deleter()} destroys \tcode{*this} since \tcode{this->get()} is no longer a valid expression. \end{note} @@ -8817,6 +9701,47 @@ \end{itemdescr} +\indexlibrary{\idxcode{make_unique}}% +\begin{itemdecl} +template unique_ptr make_unique_default_init(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is not an array. + +\pnum +\returns +\tcode{unique_ptr(new T)}. +\end{itemdescr} + +\indexlibrary{\idxcode{make_unique}}% +\begin{itemdecl} +template unique_ptr make_unique_default_init(size_t n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an array of unknown bound. + +\pnum +\returns +\tcode{unique_ptr(new remove_extent_t[n])}. +\end{itemdescr} + +\indexlibrary{\idxcode{make_unique}}% +\begin{itemdecl} +template @\unspec@ make_unique_default_init(Args&&...) = delete; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an array of known bound. +\end{itemdescr} + \rSec3[unique.ptr.special]{Specialized algorithms} \indexlibrary{\idxcode{swap(unique_ptr\&, unique_ptr\&)}}% @@ -9054,7 +9979,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum\postconditions \tcode{what()} returns an +\pnum\ensures \tcode{what()} returns an \impldef{return value of \tcode{bad_weak_ptr::what}} \ntbs{}. \end{itemdescr} @@ -9091,6 +10016,8 @@ shared_ptr(nullptr_t p, D d, A a); template shared_ptr(const shared_ptr& r, element_type* p) noexcept; + template + shared_ptr(shared_ptr&& r, element_type* p) noexcept; shared_ptr(const shared_ptr& r) noexcept; template shared_ptr(const shared_ptr& r) noexcept; @@ -9201,7 +10128,7 @@ \begin{itemdescr} \pnum\effects Constructs an empty \tcode{shared_ptr} object. -\pnum\postconditions \tcode{use_count() == 0 \&\& get() == nullptr}. +\pnum\ensures \tcode{use_count() == 0 \&\& get() == nullptr}. \end{itemdescr} \indexlibrary{\idxcode{shared_ptr}!constructor}% @@ -9227,7 +10154,7 @@ If an exception is thrown, \tcode{delete p} is called when \tcode{T} is not an array type, \tcode{delete[] p} otherwise. -\pnum\postconditions \tcode{use_count() == 1 \&\& get() == p}. +\pnum\ensures \tcode{use_count() == 1 \&\& get() == p}. \pnum\throws \tcode{bad_alloc}, or an \impldef{exception type when \tcode{shared_ptr} constructor fails} exception when a resource other than memory could not be obtained. @@ -9267,7 +10194,7 @@ allocate memory for internal use. If an exception is thrown, \tcode{d(p)} is called. -\pnum\postconditions \tcode{use_count() == 1 \&\& get() == p}. +\pnum\ensures \tcode{use_count() == 1 \&\& get() == p}. \pnum\throws \tcode{bad_alloc}, or an \impldef{exception type when \tcode{shared_ptr} constructor fails} exception @@ -9290,15 +10217,19 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} template shared_ptr(const shared_ptr& r, element_type* p) noexcept; +template shared_ptr(shared_ptr&& r, element_type* p) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs a \tcode{shared_ptr} instance that -stores \tcode{p} and shares ownership with \tcode{r}. +stores \tcode{p} and shares ownership with +the initial value of \tcode{r}. \pnum -\postconditions \tcode{get() == p \&\& use_count() == r.use_count()}. +\ensures \tcode{get() == p}. +For the second overload, +\tcode{r} is empty and \tcode{r.get() == nullptr}. \pnum \begin{note} To avoid the possibility of a dangling pointer, the @@ -9325,7 +10256,7 @@ an empty \tcode{shared_ptr} object; otherwise, constructs a \tcode{shared_ptr} object that shares ownership with \tcode{r}. -\pnum\postconditions \tcode{get() == r.get() \&\& use_count() == r.use_count()}. +\pnum\ensures \tcode{get() == r.get() \&\& use_count() == r.use_count()}. \end{itemdescr} \indexlibrary{\idxcode{shared_ptr}!constructor}% @@ -9343,7 +10274,7 @@ \effects Move constructs a \tcode{shared_ptr} instance from \tcode{r}. \pnum -\postconditions \tcode{*this} shall contain the old value of +\ensures \tcode{*this} shall contain the old value of \tcode{r}. \tcode{r} shall be empty. \tcode{r.get() == nullptr}. \end{itemdescr} @@ -9358,7 +10289,7 @@ \tcode{r} and stores a copy of the pointer stored in \tcode{r}. If an exception is thrown, the constructor has no effect. -\pnum\postconditions \tcode{use_count() == r.use_count()}. +\pnum\ensures \tcode{use_count() == r.use_count()}. \pnum\throws \tcode{bad_weak_ptr} when \tcode{r.expired()}. @@ -9642,8 +10573,11 @@ \rSec3[util.smartptr.shared.create]{Creation} \pnum -The common requirements that apply to -all \tcode{make_shared} and \tcode{allocate_shared} overloads, +The common requirements that apply to all +\tcode{make_shared}, +\tcode{allocate_shared}, +\tcode{make_shared_default_init}, and +\tcode{allocate_shared_default_init} overloads, unless specified otherwise, are described below. \indexlibrary{\idxcode{make_shared}}% @@ -9653,6 +10587,10 @@ shared_ptr make_shared(@\placeholdernc{args}@); template shared_ptr allocate_shared(const A& a, @\placeholdernc{args}@); +template + shared_ptr make_shared_default_init(@\placeholdernc{args}@); +template + shared_ptr allocate_shared_default_init(const A& a, @\placeholdernc{args}@); \end{itemdecl} \begin{itemdescr} @@ -9665,7 +10603,8 @@ (or \tcode{U[N]} when \tcode{T} is \tcode{U[]}, where \tcode{N} is determined from \placeholder{args} as specified by the concrete overload). The object is initialized from \placeholder{args} as specified by the concrete overload. -The \tcode{allocate_shared} templates use a copy of \tcode{a} +The \tcode{allocate_shared} and \tcode{allocate_shared_default_init} templates +use a copy of \tcode{a} (rebound for an unspecified \tcode{value_type}) to allocate memory. If an exception is thrown, the functions have no effect. @@ -9674,7 +10613,7 @@ the newly constructed object. \pnum -\postconditions \tcode{r.get() != 0 \&\& r.use_count() == 1}, +\ensures \tcode{r.get() != 0 \&\& r.use_count() == 1}, where \tcode{r} is the return value. \pnum @@ -9741,6 +10680,13 @@ \tcode{a2} of type \tcode{A2} is a rebound copy of the allocator \tcode{a} passed to \tcode{allocate_shared} such that its \tcode{value_type} is \tcode{remove_cv_t}. +\item + When a (sub)object of non-array type \tcode{U} is initialized by + \tcode{make_shared_default_init} or\linebreak % avoid Overfull + \tcode{allocate_shared_default_init}, + it is initialized via the expression \tcode{::new(pv) U}, + where \tcode{pv} has type \tcode{void*} and + points to storage suitable to hold an object of type \tcode{U}. \item Array elements are initialized in ascending order of their addresses. \item @@ -9748,6 +10694,20 @@ when the initialization of an array element throws an exception, the initialized elements are destroyed in the reverse order of their original construction. +\item + When a (sub)object of non-array type \tcode{U} + that was initialized by \tcode{make_shared} is to be destroyed, + it is destroyed via the expression \tcode{pv->\~{}U()} where + \tcode{pv} points to that object of type \tcode{U}. +\item + When a (sub)object of non-array type \tcode{U} + that was initialized by \tcode{allocate_shared} is to be destroyed, + it is destroyed via the expression + \tcode{allocator_traits::destroy(a2, pv)} where + \tcode{pv} points to that object of type \tcode{remove_cv_t} and + \tcode{a2} of type \tcode{A2} is a rebound copy of + the allocator \tcode{a} passed to \tcode{allocate_shared} + such that its \tcode{value_type} is \tcode{remove_cv_t}. \end{itemize} \begin{note} These functions will typically allocate more memory than \tcode{sizeof(T)} to @@ -9912,6 +10872,65 @@ \end{example} \end{itemdescr} +\indexlibrary{\idxcode{make_shared}}% +\indexlibrary{\idxcode{allocate_shared}}% +\begin{itemdecl} +template + shared_ptr make_shared_default_init(); +template + shared_ptr allocate_shared_default_init(const A& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is not an array of unknown bound. + +\pnum +\returns +A \tcode{shared_ptr} to an object of type \tcode{T}. + +\pnum +\begin{example} +\begin{codeblock} +struct X { double data[1024]; }; +shared_ptr p = make_shared_default_init(); + // \tcode{shared_ptr} to a default-initialized \tcode{X}, where each element in \tcode{X::data} has an indeterminate value + +shared_ptr q = make_shared_default_init(); + // \tcode{shared_ptr} to a default-initialized \tcode{double[1024]}, where each element has an indeterminate value +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrary{\idxcode{make_shared}}% +\indexlibrary{\idxcode{allocate_shared}}% +\begin{itemdecl} +template + shared_ptr make_shared_default_init(size_t N); +template + shared_ptr allocate_shared_default_init(const A& a, size_t N); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an array of unknown bound. + +\pnum +\returns +A \tcode{shared_ptr} to an object of type \tcode{U[N]}, +where \tcode{U} is \tcode{remove_extent_t}. + +\pnum +\begin{example} +\begin{codeblock} +shared_ptr p = make_shared_default_init(1024); + // \tcode{shared_ptr} to a default-initialized \tcode{double[1024]}, where each element has an indeterminate value +\end{codeblock} +\end{example} +\end{itemdescr} + \rSec3[util.smartptr.shared.cmp]{Comparison} \indexlibrarymember{operator==}{shared_ptr}% @@ -10052,6 +11071,8 @@ \begin{itemdecl} template shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; +template + shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -10062,8 +11083,10 @@ \pnum \returns \begin{codeblock} -shared_ptr(r, static_cast::element_type*>(r.get())) +shared_ptr(@\placeholder{R}@, static_cast::element_type*>(r.get())) \end{codeblock} +where \tcode{\placeholder{R}} is \tcode{r} for the first overload, and +\tcode{std::move(r)} for the second. \pnum \begin{note} @@ -10078,6 +11101,8 @@ \begin{itemdecl} template shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; +template + shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -10091,7 +11116,10 @@ \returns \begin{itemize} \item When \tcode{dynamic_cast::element_type*>(r.get())} -returns a non-null value \tcode{p}, \tcode{shared_ptr(r, p)}. + returns a non-null value \tcode{p}, + \tcode{shared_ptr(\placeholder{R}, p)}, + where \tcode{\placeholder{R}} is \tcode{r} for the first overload, and + \tcode{std::move(r)} for the second. \item Otherwise, \tcode{shared_ptr()}. \end{itemize} @@ -10107,6 +11135,8 @@ \begin{itemdecl} template shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; +template + shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -10117,8 +11147,10 @@ \pnum \returns \begin{codeblock} -shared_ptr(r, const_cast::element_type*>(r.get())) +shared_ptr(@\placeholder{R}@, const_cast::element_type*>(r.get())) \end{codeblock} +where \tcode{\placeholder{R}} is \tcode{r} for the first overload, and +\tcode{std::move(r)} for the second. \pnum \begin{note} @@ -10132,6 +11164,8 @@ \begin{itemdecl} template shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; +template + shared_ptr reinterpret_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -10141,8 +11175,10 @@ \pnum\returns \begin{codeblock} -shared_ptr(r, reinterpret_cast::element_type*>(r.get())) +shared_ptr(@\placeholder{R}@, reinterpret_cast::element_type*>(r.get())) \end{codeblock} +where \tcode{\placeholder{R}} is \tcode{r} for the first overload, and +\tcode{std::move(r)} for the second. \pnum \begin{note} @@ -10263,7 +11299,7 @@ \begin{itemdescr} \pnum\effects Constructs an empty \tcode{weak_ptr} object. -\pnum\postconditions \tcode{use_count() == 0}. +\pnum\ensures \tcode{use_count() == 0}. \end{itemdescr} \indexlibrary{\idxcode{weak_ptr}!constructor}% @@ -10282,7 +11318,7 @@ a \tcode{weak_ptr} object that shares ownership with \tcode{r} and stores a copy of the pointer stored in \tcode{r}. -\pnum\postconditions \tcode{use_count() == r.use_count()}. +\pnum\ensures \tcode{use_count() == r.use_count()}. \end{itemdescr} \indexlibrary{\idxcode{weak_ptr}!constructor}% @@ -10297,7 +11333,7 @@ \pnum\effects Move constructs a \tcode{weak_ptr} instance from \tcode{r}. -\pnum\postconditions \tcode{*this} shall contain the old value of \tcode{r}. +\pnum\ensures \tcode{*this} shall contain the old value of \tcode{r}. \tcode{r} shall be empty. \tcode{r.use_count() == 0}. \end{itemdescr} @@ -11178,7 +12214,7 @@ \end{codeblock} -\rSec3[mem.res.public]{\tcode{memory_resource} public member functions} +\rSec3[mem.res.public]{Public member functions} \indexlibrary{\idxcode{memory_resource}!destructor}% \begin{itemdecl} @@ -11225,7 +12261,7 @@ \end{itemdescr} -\rSec3[mem.res.private]{\tcode{memory_resource} private virtual member functions} +\rSec3[mem.res.private]{Private virtual member functions} \indexlibrarymember{do_allocate}{memory_resource}% \begin{itemdecl} @@ -11286,7 +12322,7 @@ if \tcode{dynamic_cast(\&other) == nullptr}.\end{note} \end{itemdescr} -\rSec3[mem.res.eq]{\tcode{memory_resource} equality} +\rSec3[mem.res.eq]{Equality} \indexlibrarymember{operator==}{memory_resource}% \begin{itemdecl} @@ -11322,6 +12358,10 @@ to behave as if they used different allocator types at run time even though they use the same static allocator type. +\pnum +All specializations of class template \tcode{pmr::polymorphic_allocator} +satisfy the allocator completeness requirements\iref{allocator.requirements.completeness}. + \indexlibrary{\idxcode{polymorphic_allocator}}% \indexlibrarymember{value_type}{polymorphic_allocator}% \begin{codeblock} @@ -11350,18 +12390,6 @@ template void construct(T* p, Args&&... args); - template - void construct(pair* p, piecewise_construct_t, - tuple x, tuple y); - template - void construct(pair* p); - template - void construct(pair* p, U&& x, V&& y); - template - void construct(pair* p, const pair& pr); - template - void construct(pair* p, pair&& pr); - template void destroy(T* p); @@ -11372,7 +12400,7 @@ } \end{codeblock} -\rSec3[mem.poly.allocator.ctor]{\tcode{polymorphic_allocator} constructors} +\rSec3[mem.poly.allocator.ctor]{Constructors} \indexlibrary{\idxcode{polymorphic_allocator}!constructor}% \begin{itemdecl} @@ -11421,7 +12449,7 @@ \end{itemdescr} -\rSec3[mem.poly.allocator.mem]{\tcode{polymorphic_allocator} member functions} +\rSec3[mem.poly.allocator.mem]{Member functions} \indexlibrarymember{allocate}{polymorphic_allocator}% \begin{itemdecl} @@ -11431,7 +12459,8 @@ \begin{itemdescr} \pnum \effects -Equivalent to: +If \tcode{SIZE_MAX / sizeof(Tp) < n}, throws \tcode{length_error}. +Otherwise equivalent to: \begin{codeblock} return static_cast(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp))); \end{codeblock} @@ -11466,13 +12495,10 @@ \begin{itemdescr} \pnum -\requires +\mandates Uses-allocator construction of \tcode{T} with allocator \tcode{*this} (see~\ref{allocator.uses.construction}) and constructor arguments \tcode{std::forward(args)...} is well-formed. -\begin{note} -Uses-allocator construction is always well-formed -for types that do not use allocators.\end{note} \pnum \effects @@ -11484,163 +12510,6 @@ \pnum \throws Nothing unless the constructor for \tcode{T} throws. - -\pnum -\remarks -This function shall not participate in overload resolution if -\tcode{T} is a specialization of \tcode{pair}. -\end{itemdescr} - -\indexlibrarymember{construct}{polymorphic_allocator}% -\begin{itemdecl} -template - void construct(pair* p, piecewise_construct_t, tuple x, tuple y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\begin{note} -This member function and the \tcode{construct} member functions that follow -are overloads for piecewise construction of pairs\iref{pairs.pair}. -\end{note} - -\pnum -\effects -Let \tcode{xprime} be a \tcode{tuple} constructed from \tcode{x} -according to the appropriate rule from the following list. -\begin{note} -The following description can be summarized as -constructing a \tcode{pair} object -in the storage whose address is represented by \tcode{p}, -as if by separate uses-allocator construction -with allocator \tcode{*this}\iref{allocator.uses.construction} -of \tcode{p->first} using the elements of \tcode{x} -and \tcode{p->second} using the elements of \tcode{y}. -\end{note} -\begin{itemize} -\item -If \tcode{uses_allocator_v} is \tcode{false} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then \tcode{xprime} is \tcode{x}. -\item -Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then \tcode{xprime} is \tcode{tuple_cat(make_tuple(allocator_arg, *this), std::move(x))}. -\item -Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then \tcode{xprime} is \tcode{tuple_cat(std::move(x), make_tuple(*this))}. -\item -Otherwise the program is ill formed. -\end{itemize} -Let \tcode{yprime} be a tuple constructed from \tcode{y} -according to the appropriate rule from the following list: -\begin{itemize} -\item -If \tcode{uses_allocator_v} is \tcode{false} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then \tcode{yprime} is \tcode{y}. -\item -Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then \tcode{yprime} is \tcode{tuple_cat(make_tuple(allocator_arg, *this), std::move(y))}. -\item -Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -\\ -and -\tcode{is_constructible_v} is \tcode{true}, -\\ -then -\tcode{yprime} is \tcode{tuple_cat(std::move(y), make_tuple(*this))}. -\item -Otherwise the program is ill formed. -\end{itemize} - -Then, using \tcode{piecewise_construct}, \tcode{xprime}, and \tcode{yprime} -as the constructor arguments, -this function constructs a \tcode{pair} object -in the storage whose address is represented by \tcode{p}. -\end{itemdescr} - -\indexlibrarymember{construct}{polymorphic_allocator}% -\begin{itemdecl} -template - void construct(pair* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, tuple<>(), tuple<>()); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{polymorphic_allocator}% -\begin{itemdecl} -template - void construct(pair* p, U&& x, V&& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(std::forward(x)), - forward_as_tuple(std::forward(y))); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{polymorphic_allocator}% -\begin{itemdecl} -template - void construct(pair* p, const pair& pr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(pr.first), - forward_as_tuple(pr.second)); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{polymorphic_allocator}% -\begin{itemdecl} -template - void construct(pair* p, pair&& pr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(std::forward(pr.first)), - forward_as_tuple(std::forward(pr.second))); -\end{codeblock} \end{itemdescr} \indexlibrarymember{destroy}{polymorphic_allocator}% @@ -11682,7 +12551,7 @@ \tcode{memory_rsrc}. \end{itemdescr} -\rSec3[mem.poly.allocator.eq]{\tcode{polymorphic_allocator} equality} +\rSec3[mem.poly.allocator.eq]{Equality} \indexlibrarymember{operator==}{polymorphic_allocator}% \begin{itemdecl} @@ -11945,7 +12814,7 @@ larger than specified in this field. \end{itemdescr} -\rSec3[mem.res.pool.ctor]{Pool resource constructors and destructors} +\rSec3[mem.res.pool.ctor]{Constructors and destructors} \indexlibrary{\idxcode{synchronized_pool_resource}!constructor}% \indexlibrary{\idxcode{unsynchronized_pool_resource}!constructor}% @@ -11993,7 +12862,7 @@ Calls \tcode{release()}. \end{itemdescr} -\rSec3[mem.res.pool.mem]{Pool resource members} +\rSec3[mem.res.pool.mem]{Members} \indexlibrarymember{release}{synchronized_pool_resource}% \indexlibrarymember{release}{unsynchronized_pool_resource}% @@ -12167,7 +13036,7 @@ } \end{codeblock} -\rSec3[mem.res.monotonic.buffer.ctor]{\tcode{monotonic_buffer_resource} constructor and destructor} +\rSec3[mem.res.monotonic.buffer.ctor]{Constructors and destructor} \indexlibrary{\idxcode{monotonic_buffer_resource}!constructor}% \begin{itemdecl} @@ -12223,7 +13092,7 @@ \end{itemdescr} -\rSec3[mem.res.monotonic.buffer.mem]{\tcode{monotonic_buffer_resource} members} +\rSec3[mem.res.monotonic.buffer.mem]{Members} \indexlibrarymember{release}{monotonic_buffer_resource}% \begin{itemdecl} @@ -12426,17 +13295,6 @@ template void construct(T* p, Args&&... args); - template - void construct(pair* p, piecewise_construct_t, - tuple x, tuple y); - template - void construct(pair* p); - template - void construct(pair* p, U&& x, V&& y); - template - void construct(pair* p, const pair& x); - template - void construct(pair* p, pair&& x); template void destroy(T* p); @@ -12450,7 +13308,7 @@ } \end{codeblock} -\rSec2[allocator.adaptor.types]{Scoped allocator adaptor member types} +\rSec2[allocator.adaptor.types]{Member types} \indexlibrarymember{inner_allocator_type}{scoped_allocator_adaptor}% \begin{itemdecl} @@ -12515,7 +13373,7 @@ \tcode{InnerAllocs...}; otherwise, \tcode{false_type}. \end{itemdescr} -\rSec2[allocator.adaptor.cnstr]{Scoped allocator adaptor constructors} +\rSec2[allocator.adaptor.cnstr]{Constructors} \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% \begin{itemdecl} @@ -12601,18 +13459,19 @@ \tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} -\rSec2[allocator.adaptor.members]{Scoped allocator adaptor members} +\rSec2[allocator.adaptor.members]{Members} \pnum In the \tcode{construct} member functions, -\tcode{\placeholdernc{OUTERMOST}(x)} is \tcode{x} if \tcode{x} does not have an -\tcode{outer_allocator()} member function and -\tcode{\placeholdernc{OUTERMOST}(x.outer_allocator())} -otherwise; +\tcode{\placeholdernc{OUTERMOST}(x)} is +\tcode{\placeholdernc{OUTERMOST}(x.outer_allocator())} if +the expression \tcode{x.outer_allocator()} is +valid~\iref{temp.deduct} and +\tcode{x} otherwise; \tcode{\placeholdernc{OUTERMOST_ALLOC_TRAITS}(x)} is -\tcode{allocator_traits}. +\tcode{allocator_traits>}. \begin{note} \tcode{\placeholdernc{OUTERMOST}(x)} and -\tcode{\placeholdernc{OUTERMOST_ALLOC_TRAITS}(x)} are recursive operations. It +\tcode{\placeholdernc{OUTERMOST_ALL\-OC_TRAITS}(x)} are recursive operations. It is incumbent upon the definition of \tcode{outer_allocator()} to ensure that the recursion terminates. It will terminate for all instantiations of \tcode{scoped_allocator_adaptor}. \end{note} @@ -12699,173 +13558,15 @@ \begin{itemdescr} \pnum \effects -\begin{itemize} -\item If \tcode{uses_allocator_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}, calls: -\begin{codeblock} -@\placeholdernc{OUTERMOST_ALLOC_TRAITS}@(*this)::construct( - @\placeholdernc{OUTERMOST}@(*this), p, std::forward(args)...) -\end{codeblock} - -\item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and -\tcode{is_constructible_v} is \tcode{true}, calls: -\begin{codeblock} -@\placeholdernc{OUTERMOST_ALLOC_TRAITS}@(*this)::construct( - @\placeholdernc{OUTERMOST}@(*this), p, allocator_arg, inner_allocator(), std::forward(args)...) -\end{codeblock} - -\item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and -\tcode{is_constructible_v} is \tcode{true}, calls: -\begin{codeblock} -@\placeholdernc{OUTERMOST_ALLOC_TRAITS}@(*this)::construct( - @\placeholdernc{OUTERMOST}@(*this), p, std::forward(args)..., inner_allocator()) -\end{codeblock} - -\item Otherwise, the program is ill-formed. -\begin{note} -An error will result if -\tcode{uses_allocator} evaluates to \tcode{true} but the specific constructor does not take an -allocator. This definition prevents a silent failure to pass an inner allocator to a -contained element. -\end{note} -\end{itemize} - -\pnum -\remarks -This function shall not participate in overload resolution if -\tcode{T} is a specialization of \tcode{pair}. -\end{itemdescr} - -\indexlibrarymember{construct}{scoped_allocator_adaptor}% -\begin{itemdecl} -template - void construct(pair* p, piecewise_construct_t, tuple x, tuple y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs a \tcode{tuple} object \tcode{xprime} from \tcode{x} by the -following rules: -\begin{itemize} -\item If \tcode{uses_allocator_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}, -then \tcode{xprime} is \tcode{tuple(std::move(x))}. - -\item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -and -\tcode{is_construct\-ible_v} -is -\tcode{true}, then \tcode{xprime} is: -\begin{codeblock} -tuple_cat( - tuple(allocator_arg, inner_allocator()), - tuple(std::move(x))) -\end{codeblock} - -\item Otherwise, if \tcode{uses_allocator_v} is -\tcode{true} and -\tcode{is_construct\-ible_v} is \tcode{true}, -then \tcode{xprime} is: -\begin{codeblock} -tuple_cat(tuple(std::move(x)), - tuple(inner_allocator())) -\end{codeblock} - -\item Otherwise, the program is ill-formed. -\end{itemize} -and constructs a \tcode{tuple} object \tcode{yprime} from \tcode{y} by the following rules: -\begin{itemize} -\item If \tcode{uses_allocator_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}, then \tcode{yprime} is \tcode{tuple(std::move(y)}. - -\item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} -and -\tcode{is_constructible_v} -is -\tcode{true}, then \tcode{yprime} is: -\begin{codeblock} -tuple_cat( - tuple(allocator_arg, inner_allocator()), - tuple(std::move(y))) -\end{codeblock} - -\item Otherwise, if \tcode{uses_allocator_v} is -\tcode{true} and -\tcode{is_constructible_v} is \tcode{true}, -then \tcode{yprime} is: -\begin{codeblock} -tuple_cat(tuple(std::move(y)), - tuple(inner_allocator())) -\end{codeblock} - -\item Otherwise, the program is ill-formed. -\end{itemize} -then calls: -\begin{codeblock} -@\placeholdernc{OUTERMOST_ALLOC_TRAITS}@(*this)::construct( - @\placeholdernc{OUTERMOST}@(*this), p, piecewise_construct, std::move(xprime), std::move(yprime)) -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{scoped_allocator_adaptor}% -\begin{itemdecl} -template - void construct(pair* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, tuple<>(), tuple<>()); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{scoped_allocator_adaptor}% -\begin{itemdecl} -template - void construct(pair* p, U&& x, V&& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(std::forward(x)), - forward_as_tuple(std::forward(y))); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{scoped_allocator_adaptor}% -\begin{itemdecl} -template - void construct(pair* p, const pair& x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(x.first), - forward_as_tuple(x.second)); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{construct}{scoped_allocator_adaptor}% -\begin{itemdecl} -template - void construct(pair* p, pair&& x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: +Equivalent to: \begin{codeblock} -construct(p, piecewise_construct, - forward_as_tuple(std::forward(x.first)), - forward_as_tuple(std::forward(x.second))); +apply([p, this](auto&&... newargs) { + @\placeholdernc{OUTERMOST_ALLOC_TRAITS}@(*this)::construct( + @\placeholdernc{OUTERMOST}@(*this), p, + std::forward(newargs)...); + }, + uses_allocator_construction_args(inner_allocator(), + std::forward(args)...)); \end{codeblock} \end{itemdescr} @@ -12893,7 +13594,7 @@ corresponding allocator in \tcode{*this}. \end{itemdescr} -\rSec2[scoped.adaptor.operators]{Scoped allocator operators} +\rSec2[scoped.adaptor.operators]{Operators} \indexlibrarymember{operator==}{scoped_allocator_adaptor}% \begin{itemdecl} @@ -12944,6 +13645,8 @@ \rSec2[functional.syn]{Header \tcode{} synopsis} \indexhdr{functional}% +\indexlibrary{\idxcode{unwrap_ref_decay}}% +\indexlibrary{\idxcode{unwrap_ref_decay_t}}% \begin{codeblock} namespace std { // \ref{func.invoke}, invoke @@ -12962,6 +13665,10 @@ template reference_wrapper ref(reference_wrapper) noexcept; template reference_wrapper cref(reference_wrapper) noexcept; + template struct unwrap_reference; + template struct unwrap_ref_decay : unwrap_reference> {}; + template using unwrap_ref_decay_t = typename unwrap_ref_decay::type; + // \ref{arithmetic.operations}, arithmetic operations template struct plus; template struct minus; @@ -13014,6 +13721,9 @@ // \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}, bind template struct is_bind_expression; template struct is_placeholder; @@ -13078,6 +13788,40 @@ inline constexpr bool is_bind_expression_v = is_bind_expression::value; template inline constexpr int is_placeholder_v = is_placeholder::value; + + namespace ranges { + // \ref{range.cmp}, range 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} @@ -13127,6 +13871,17 @@ \pnum A \defn{target object} is the callable object held by a call wrapper. +\pnum +A call wrapper type may additionally hold +a sequence of objects and references +that may be passed as arguments to the target object. +These entities are collectively referred to +as \defnx{bound argument entities}{bound argument entity}. + +\pnum +The target object and bound argument entities of the call wrapper are +collectively referred to as \defnx{state entities}{state entity}. + \rSec2[func.require]{Requirements} \pnum @@ -13173,28 +13928,64 @@ \indextext{call wrapper}% \indextext{call wrapper!simple}% \indextext{call wrapper!forwarding}% -Every call wrapper\iref{func.def} shall be -\oldconcept{MoveConstructible}. -A \defn{forwarding call wrapper} is a +Every call wrapper\iref{func.def} is \oldconcept{MoveConstructible}. +A \defn{argument forwarding call wrapper} is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the wrapped callable object as references. -This forwarding step shall ensure that rvalue arguments are delivered as rvalue references -and lvalue arguments are delivered as lvalue references. -A \defn{simple call wrapper} is a forwarding call wrapper that is +This forwarding step delivers rvalue arguments as rvalue references +and lvalue arguments as lvalue references. +A \defn{simple call wrapper} is an argument forwarding call wrapper that is \oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} and whose copy constructor, move constructor, copy assignment operator, and move assignment operator do not throw exceptions. \begin{note} -In a typical implementation -forwarding call wrappers have an overloaded function call -operator of -the form +In a typical implementation, argument forwarding call wrappers have +an overloaded function call operator of the form \begin{codeblock} template R operator()(UnBoundArgs&&... unbound_args) @\textit{cv-qual}@; \end{codeblock} \end{note} +\pnum +\indextext{call wrapper!perfect forwarding}% +A \defn{perfect forwarding call wrapper} is +an argument forwarding call wrapper +that forwards its state entities to the underlying call expression. +This forwarding step delivers a state entity of type \tcode{T} +as \cv{} \tcode{T\&} +when the call is performed on an lvalue of the call wrapper type and +as \cv{} \tcode{T\&\&} otherwise, +where \cv{} represents the cv-qualifiers of the call wrapper and +where \cv{} shall be neither \tcode{volatile} nor \tcode{const volatile}. + +\pnum +A \defn{call pattern} defines the semantics of invoking +a perfect forwarding call wrapper. +A postfix call performed on a perfect forwarding call wrapper is +expression-equivalent\iref{defns.expression-equivalent} to +an expression \tcode{e} determined from its call pattern \tcode{cp} +by replacing all occurrences +of the arguments of the call wrapper and its state entities +with references as described in the corresponding forwarding steps. + +\pnum +The copy/move constructor of a perfect forwarding call wrapper has +the same apparent semantics +as if memberwise copy/move of its state entities +were performed\iref{class.copy.ctor}. +\begin{note} +This implies that each of the copy/move constructors has +the same exception-specification as +the corresponding implicit definition and is declared as \tcode{constexpr} +if the corresponding implicit definition would be considered to be constexpr. +\end{note} + +\pnum +Perfect forwarding call wrappers returned by +a given standard library function template have the same type +if the types of their corresponding state entities are the same. + \rSec2[func.invoke]{Function template \tcode{invoke}} \indexlibrary{\idxcode{invoke}}% \indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% @@ -13249,7 +14040,11 @@ \pnum \tcode{reference_wrapper} is a trivially copyable type\iref{basic.types}. -\rSec3[refwrap.const]{\tcode{reference_wrapper} construct/copy/destroy} +\pnum +The template parameter \tcode{T} of \tcode{reference_wrapper} +may be an incomplete type. + +\rSec3[refwrap.const]{Constructors and destructor} \indexlibrary{\idxcode{reference_wrapper}!constructor}% \begin{itemdecl} @@ -13287,7 +14082,7 @@ stores a reference to \tcode{x.get()}. \end{itemdescr} -\rSec3[refwrap.assign]{\tcode{reference_wrapper} assignment} +\rSec3[refwrap.assign]{Assignment} \indexlibrarymember{operator=}{reference_wrapper}% \begin{itemdecl} @@ -13295,10 +14090,10 @@ \end{itemdecl} \begin{itemdescr} -\pnum\postconditions \tcode{*this} stores a reference to \tcode{x.get()}. +\pnum\ensures \tcode{*this} stores a reference to \tcode{x.get()}. \end{itemdescr} -\rSec3[refwrap.access]{\tcode{reference_wrapper} access} +\rSec3[refwrap.access]{Access} \indexlibrarymember{operator T\&}{reference_wrapper}% \begin{itemdecl} @@ -13318,8 +14113,7 @@ \pnum\returns The stored reference. \end{itemdescr} - -\rSec3[refwrap.invoke]{\tcode{reference_wrapper} invocation} +\rSec3[refwrap.invoke]{Invocation} \indexlibrarymember{operator()}{reference_wrapper}% \begin{itemdecl} @@ -13329,11 +14123,20 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + \pnum\returns \tcode{\placeholdernc{INVOKE}(get(), std::forward(args)...)}.\iref{func.require} \end{itemdescr} -\rSec3[refwrap.helpers]{\tcode{reference_wrapper} helper functions} +\rSec3[refwrap.helpers]{Helper functions} + +\pnum +The template parameter \tcode{T} of +the following \tcode{ref} and \tcode{cref} function templates +may be an incomplete type. \indexlibrarymember{ref}{reference_wrapper}% \begin{itemdecl} @@ -13371,6 +14174,20 @@ \pnum\returns \tcode{cref(t.get())}. \end{itemdescr} +\rSec3[refwrap.unwrapref]{Transformation type trait \tcode{unwrap_reference}} + +\indexlibrary{\idxcode{unwrap_reference}}% +\begin{itemdecl} +template + struct unwrap_reference; +\end{itemdecl} + +\pnum +If \tcode{T} is +a specialization \tcode{reference_wrapper} for some type \tcode{X}, +the member typedef \tcode{type} of \tcode{unwrap_reference} is \tcode{X\&}, +otherwise it is \tcode{T}. + \rSec2[arithmetic.operations]{Arithmetic operations} \pnum @@ -13857,6 +14674,263 @@ \pnum\returns \tcode{std::forward(t) <= std::forward(u)}. \end{itemdescr} +\rSec2[range.cmp]{Range comparisons} + +\pnum +In this subclause, \tcode{\placeholdernc{BUILTIN_PTR_CMP}(T, $op$, U)} for types \tcode{T} +and \tcode{U} and where $op$ is an equality\iref{expr.eq} or relational +operator\iref{expr.rel} is a boolean constant expression. +\tcode{\placeholdernc{BUILTIN_PTR_CMP}(T, $op$, U)} is \tcode{true} if and only if $op$ +in the expression \tcode{declval() $op$ declval()} resolves to a built-in +operator comparing pointers. + +\pnum +There is an implementation-defined strict total ordering over all pointer values +of a given type. This total ordering is consistent with the partial order imposed +by the builtin operators \tcode{<}, \tcode{>}, \tcode{<=}, and \tcode{>=}. + +\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; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If the expression \tcode{std::forward(t) == std::forward(u)} +results in a call to a built-in operator \tcode{==} comparing pointers of type +\tcode{P}, the conversion sequences from both \tcode{T} and \tcode{U} to \tcode{P} +shall be equality-preserving\iref{concepts.equality}. + +\pnum +\effects +\begin{itemize} +\item + If the expression \tcode{std::forward(t) == std::forward(u)} results in + a call to a built-in operator \tcode{==} comparing pointers of type \tcode{P}: + returns \tcode{false} if either (the converted value of) \tcode{t} precedes + \tcode{u} or \tcode{u} precedes \tcode{t} in the implementation-defined strict + total order over pointers of type \tcode{P} and otherwise \tcode{true}. + +\item + Otherwise, equivalent to: + \tcode{return std::forward(t) == std::forward(u);} +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{not_equal_to<>}}% +\begin{itemdecl} +template<> struct ranges::not_equal_to { + template + requires EqualityComparableWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, ==, U) + constexpr bool operator()(T&& t, U&& u) const; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{operator()} has effects equivalent to: +\begin{codeblock} +return !ranges::equal_to<>{}(std::forward(t), std::forward(u)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{greater<>}}% +\begin{itemdecl} +template<> struct ranges::greater { + template + requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(U, <, T) + constexpr bool operator()(T&& t, U&& u) const; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{operator()} has effects equivalent to: +\begin{codeblock} +return ranges::less<>{}(std::forward(u), std::forward(t)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{less<>}}% +\begin{itemdecl} +template<> struct ranges::less { + template + requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, <, U) + constexpr bool operator()(T&& t, U&& u) const; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If the expression \tcode{std::forward(t) < std::forward(u)} results in a +call to a built-in operator \tcode{<} comparing pointers of type \tcode{P}, the +conversion sequences from both \tcode{T} and \tcode{U} to \tcode{P} shall be +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)} +shall be \tcode{true}. + +\pnum +\effects +\begin{itemize} +\item +If the expression \tcode{std::forward(t) < std::forward(u)} results in a +call to a built-in operator \tcode{<} comparing pointers of type \tcode{P}: +returns \tcode{true} if (the converted value of) \tcode{t} precedes \tcode{u} in +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<>}}% +\begin{itemdecl} +template<> struct ranges::greater_equal { + template + requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(T, <, U) + constexpr bool operator()(T&& t, U&& u) const; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{operator()} has effects equivalent to: +\begin{codeblock} +return !ranges::less<>{}(std::forward(t), std::forward(u)); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{less_equal<>}}% +\begin{itemdecl} +template<> struct ranges::less_equal { + template + requires StrictTotallyOrderedWith || @\placeholdernc{BUILTIN_PTR_CMP}@(U, <, T) + constexpr bool operator()(T&& t, U&& u) const; + + using is_transparent = @\unspecnc@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{operator()} has effects equivalent to: +\begin{codeblock} +return !ranges::less<>{}(std::forward(u), std::forward(t)); +\end{codeblock} +\end{itemdescr} \rSec2[logical.operations]{Logical operations} @@ -14169,93 +15243,90 @@ \begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{return \placeholder{call-wrapper}(std::forward(f));} -where \tcode{\placeholder{call-wrapper}} is an exposition only class defined as follows: -\begin{codeblock} -class @\placeholder{call-wrapper}@ { - using FD = decay_t; - FD fd; - - explicit @\placeholder{call-wrapper}@(F&& f); - -public: - @\placeholder{call-wrapper}@(@\placeholder{call-wrapper}@&&) = default; - @\placeholder{call-wrapper}@(const @\placeholder{call-wrapper}@&) = default; - - template - auto operator()(Args&&...) & - -> decltype(!declval>()); - - template - auto operator()(Args&&...) const& - -> decltype(!declval>()); - - template - auto operator()(Args&&...) && - -> decltype(!declval>()); - - template - auto operator()(Args&&...) const&& - -> decltype(!declval>()); -}; -\end{codeblock} -\end{itemdescr} +In the text that follows: +\begin{itemize} +\item \tcode{g} is a value of the result of a \tcode{not_fn} invocation, +\item \tcode{FD} is the type \tcode{decay_t}, +\item \tcode{fd} is the target object of \tcode{g}\iref{func.def} + of type \tcode{FD}, + initialized with + the \grammarterm{initializer} \tcode{(std::forward(f\brk{}))}\iref{dcl.init}, +\item \tcode{call_args} is an argument pack + used in a function call expression\iref{expr.call} of \tcode{g}. +\end{itemize} -\begin{itemdecl} -explicit @\placeholdernc{call-wrapper}@(F&& f); -\end{itemdecl} +\pnum +\mandates +\tcode{is_constructible_v \&\& is_move_constructible_v} +shall be true. -\begin{itemdescr} \pnum -\requires -\tcode{FD} shall satisfy the \oldconcept{MoveConstructible} requirements. -\tcode{is_constructible_v} shall be \tcode{true}. -\tcode{fd} shall be a callable object\iref{func.def}. +\expects +\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. \pnum -\effects -Initializes \tcode{fd} from \tcode{std::forward(f)}. +\returns +A perfect forwarding call wrapper \tcode{g} +with call pattern \tcode{!invoke(fd, call_args...)}. \pnum \throws -Any exception thrown by construction of \tcode{fd}. +Any exception thrown by the initialization of \tcode{fd}. \end{itemdescr} +\rSec2[func.bind_front]{Function template \tcode{bind_front}} + +\indexlibrary{\idxcode{bind_front}}% \begin{itemdecl} -template - auto operator()(Args&&... args) & - -> decltype(!declval>()); -template - auto operator()(Args&&... args) const& - -> decltype(!declval>()); +template + @\unspec@ bind_front(F&& f, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: +In the text that follows: +\begin{itemize} +\item \tcode{g} is a value of the result of a \tcode{bind_front} invocation, +\item \tcode{FD} is the type \tcode{decay_t}, +\item \tcode{fd} is the target object of \tcode{g}\iref{func.def} + of type \tcode{FD} initialized with + the \grammarterm{initializer} \tcode{(std::forward(\brk{}f))}\iref{dcl.init}, +\item \tcode{BoundArgs} is a pack + that denotes \tcode{std::unwrap_ref_decay_t...}, +\item \tcode{bound_args} is + a pack of bound argument entities of \tcode{g}\iref{func.def} + of types \tcode{BoundArgs...}, + initialized with + \grammarterm{initializer}{s} \tcode{(std::forward(args))...}, + respectively, and +\item \tcode{call_args} is an argument pack used in + a function call expression\iref{expr.call} of \tcode{g}. +\end{itemize} + +\pnum +\mandates \begin{codeblock} -return !@\placeholdernc{INVOKE}@(fd, std::forward(args)...); // see \ref{func.require} +conjunction_v, is_move_constructible, + is_constructible..., is_move_constructible...> \end{codeblock} -\end{itemdescr} +shall be true. -\begin{itemdecl} -template - auto operator()(Args&&... args) && - -> decltype(!declval>()); -template - auto operator()(Args&&... args) const&& - -> decltype(!declval>()); -\end{itemdecl} +\pnum +\expects +\tcode{FD} shall meet the requirements of \oldconcept{MoveConstructible}. +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}. -\begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -return !@\placeholdernc{INVOKE}@(std::move(fd), std::forward(args)...); // see \ref{func.require} -\end{codeblock} +\returns +A perfect forwarding call wrapper \tcode{g} +with call pattern \tcode{invoke(fd, bound_args..., call_args...)}. + +\pnum +\throws +Any exception thrown by +the initialization of the state entities of \tcode{g}\iref{func.def}. \end{itemdescr} \rSec2[func.bind]{Function object binders}% @@ -14329,7 +15400,7 @@ \item $\tcode{t}_i$ is the $i^\text{th}$ argument in the function parameter pack \tcode{bound_args}, \item $\tcode{td}_i$ is an lvalue of type $\tcode{TD}_i$ constructed from \tcode{std::forward<$\tcode{T}_i$>($\tcode{t}_i$)}, \item $\tcode{U}_j$ is the $j^\text{th}$ deduced type of the \tcode{UnBoundArgs\&\&...} parameter - of the forwarding call wrapper, and + of the argument forwarding call wrapper, and \item $\tcode{u}_j$ is the $j^\text{th}$ argument associated with $\tcode{U}_j$. \end{itemize} @@ -14352,7 +15423,7 @@ as specified below, shall be neither \tcode{volatile} nor \tcode{const volatile}. \pnum\returns -A forwarding call wrapper \tcode{g}\iref{func.require}. +An argument forwarding call wrapper \tcode{g}\iref{func.require}. The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall be \begin{codeblock} @@ -14360,7 +15431,7 @@ \end{codeblock} where the values and types of the bound arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below. -The copy constructor and move constructor of the forwarding call wrapper shall throw an +The copy constructor and move constructor of the argument forwarding call wrapper shall throw an exception if and only if the corresponding constructor of \tcode{FD} or of any of the types $\tcode{TD}_i$ throws an exception. @@ -14395,7 +15466,7 @@ \pnum \returns -A forwarding call wrapper \tcode{g}\iref{func.require}. +An argument forwarding call wrapper \tcode{g}\iref{func.require}. The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, $\dotsc$, $\tcode{u}_M$)} shall be \begin{codeblock} @@ -14403,7 +15474,7 @@ \end{codeblock} where the values and types of the bound arguments $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ are determined as specified below. -The copy constructor and move constructor of the forwarding call wrapper shall throw an +The copy constructor and move constructor of the argument forwarding call wrapper shall throw an exception if and only if the corresponding constructor of \tcode{FD} or of any of the types $\tcode{TD}_i$ throws an exception. @@ -14521,7 +15592,7 @@ } \end{codeblock} -\rSec4[func.wrap.badcall.const]{\tcode{bad_function_call} constructor} +\rSec4[func.wrap.badcall.const]{Constructor} \indexlibrary{\idxcode{bad_function_call}!constructor}% \indexlibrarymember{what}{bad_function_call}% @@ -14534,7 +15605,7 @@ \end{itemdescr} \begin{itemdescr} -\pnum\postconditions \tcode{what()} returns an +\pnum\ensures \tcode{what()} returns an \impldef{return value of \tcode{bad_function_call::what}} \ntbs{}. \end{itemdescr} @@ -14554,7 +15625,7 @@ function() noexcept; function(nullptr_t) noexcept; function(const function&); - function(function&&); + function(function&&) noexcept; template function(F); function& operator=(const function&); @@ -14632,7 +15703,7 @@ may change in future versions of this International Standard. \end{note} -\rSec4[func.wrap.func.con]{\tcode{function} construct/copy/destroy} +\rSec4[func.wrap.func.con]{Constructors and destructor} \indexlibrary{\idxcode{function}!constructor}% \begin{itemdecl} @@ -14640,7 +15711,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum\postconditions \tcode{!*this}. +\pnum\ensures \tcode{!*this}. \end{itemdescr} \indexlibrary{\idxcode{function}!constructor}% @@ -14650,7 +15721,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{!*this}. +\ensures \tcode{!*this}. \end{itemdescr} \indexlibrary{\idxcode{function}!constructor}% @@ -14660,7 +15731,7 @@ \begin{itemdescr} \pnum -\postconditions \tcode{!*this} if \tcode{!f}; otherwise, +\ensures \tcode{!*this} if \tcode{!f}; otherwise, \tcode{*this} targets a copy of \tcode{f.target()}. \pnum @@ -14676,22 +15747,17 @@ \indexlibrary{\idxcode{function}!constructor}% \begin{itemdecl} -function(function&& f); +function(function&& f) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postconditions If \tcode{!f}, \tcode{*this} has no target; +\ensures If \tcode{!f}, \tcode{*this} has no target; otherwise, the target of \tcode{*this} is equivalent to the target of \tcode{f} before the construction, and \tcode{f} is in a valid state with an unspecified value. \pnum -\throws Shall not throw exceptions if \tcode{f}'s target is -a specialization of \tcode{reference_wrapper} or -a function pointer. Otherwise, may throw \tcode{bad_alloc} or -any exception thrown by the copy or move constructor -of the stored callable object. \begin{note} Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where \tcode{f}'s target is an object holding only a pointer or reference @@ -14713,7 +15779,7 @@ \tcode{ArgTypes...} and return type \tcode{R}. \pnum -\postconditions \tcode{!*this} if any of the following hold: +\ensures \tcode{!*this} if any of the following hold: \begin{itemize} \item \tcode{f} is a null function pointer value. \item \tcode{f} is a null member pointer value. @@ -14795,7 +15861,7 @@ \begin{itemdescr} \pnum\effects If \tcode{*this != nullptr}, destroys the target of \tcode{this}. -\pnum\postconditions \tcode{!(*this)}. +\pnum\ensures \tcode{!(*this)}. \pnum\returns \tcode{*this}. \end{itemdescr} @@ -14837,7 +15903,7 @@ \pnum\effects If \tcode{*this != nullptr}, destroys the target of \tcode{this}. \end{itemdescr} -\rSec4[func.wrap.func.mod]{\tcode{function} modifiers} +\rSec4[func.wrap.func.mod]{Modifiers} \indexlibrarymember{swap}{function}% \begin{itemdecl} @@ -14848,7 +15914,7 @@ \pnum\effects Interchanges the targets of \tcode{*this} and \tcode{other}. \end{itemdescr} -\rSec4[func.wrap.func.cap]{\tcode{function} capacity} +\rSec4[func.wrap.func.cap]{Capacity} \indexlibrarymember{operator bool}{function}% \begin{itemdecl} @@ -14860,7 +15926,7 @@ \returns \tcode{true} if \tcode{*this} has a target, otherwise \tcode{false}. \end{itemdescr} -\rSec4[func.wrap.func.inv]{\tcode{function} invocation} +\rSec4[func.wrap.func.inv]{Invocation} \indexlibrary{\idxcode{function}!invocation}% \indexlibrarymember{operator()}{function}% @@ -14878,7 +15944,7 @@ exception thrown by the wrapped callable object. \end{itemdescr} -\rSec4[func.wrap.func.targ]{\tcode{function} target access} +\rSec4[func.wrap.func.targ]{Target access} \indexlibrarymember{target_type}{function}% \begin{itemdecl} @@ -14901,7 +15967,7 @@ a pointer to the stored function target; otherwise a null pointer. \end{itemdescr} -\rSec4[func.wrap.func.nullptr]{null pointer comparison functions} +\rSec4[func.wrap.func.nullptr]{Null pointer comparison functions} \indexlibrarymember{operator==}{function}% \begin{itemdecl} @@ -14927,7 +15993,7 @@ \pnum\returns \tcode{(bool)f}. \end{itemdescr} -\rSec4[func.wrap.func.alg]{specialized algorithms} +\rSec4[func.wrap.func.alg]{Specialized algorithms} \indexlibrarymember{swap}{function}% \begin{itemdecl} @@ -14981,11 +16047,11 @@ template> class default_searcher { public: - default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, - BinaryPredicate pred = BinaryPredicate()); + constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, + BinaryPredicate pred = BinaryPredicate()); template - pair + constexpr pair operator()(ForwardIterator2 first, ForwardIterator2 last) const; private: @@ -14997,8 +16063,8 @@ \indexlibrary{\idxcode{default_searcher}!constructor}% \begin{itemdecl} -default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, - BinaryPredicate pred = BinaryPredicate()); +constexpr default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, + BinaryPredicate pred = BinaryPredicate()); \end{itemdecl} \begin{itemdescr} @@ -15018,7 +16084,7 @@ \indexlibrarymember{operator()}{default_searcher}% \begin{itemdecl} template - pair + constexpr pair operator()(ForwardIterator2 first, ForwardIterator2 last) const; \end{itemdecl} @@ -15338,6 +16404,26 @@ define the modification. It shall define a publicly accessible nested type named \tcode{type}, which shall be a synonym for the modified type. +\pnum +Unless otherwise specified, +the behavior of a program that adds specializations +for any of the templates specified in this subclause~\ref{meta} +is undefined. + +\pnum +Unless otherwise specified, an incomplete type may be used +to instantiate a template specified in this subclause. +The behavior of a program is undefined if: +\begin{itemize} +\item + an instantiation of a template specified in this subclause + directly or indirectly depends on + an incompletely-defined object type \tcode{T}, and +\item + that instantiation could yield a different result + were \tcode{T} hypothetically completed. +\end{itemize} + \rSec2[meta.type.synop]{Header \tcode{} synopsis} \indexhdr{type_traits}% @@ -15744,17 +16830,12 @@ inline constexpr bool disjunction_v = disjunction::value; template inline constexpr bool negation_v = negation::value; + + // \ref{meta.const.eval}, constant evaluation context + constexpr bool is_constant_evaluated() noexcept; } \end{codeblock} -\pnum -The behavior of a program that adds specializations for any of -the templates defined in this subclause is undefined unless otherwise specified. - -\pnum -Unless otherwise specified, an incomplete type may be used -to instantiate a template in this subclause. - \rSec2[meta.help]{Helper classes} \indexlibrarymember{value_type}{integral_constant}% @@ -16415,7 +17496,7 @@ The set of scalar types for which this condition holds is \impldef{which scalar types have unique object representations}. \begin{note} If a type has padding bits, the condition does not hold; -otherwise, the condition holds true for unsigned integral types. \end{note} +otherwise, the condition holds true for integral types. \end{note} \rSec2[meta.unary.prop.query]{Type property queries} @@ -17021,17 +18102,13 @@ \end{codeblock} \end{note} -\pnum -It is \impldef{support for extended alignment} whether any extended alignment is -supported\iref{basic.align}. - \indexlibrary{\idxcode{common_type}}% \pnum Let: \begin{itemize} \item \tcode{\placeholdernc{CREF}(A)} be \tcode{add_lvalue_reference_t{}>}, -\item \tcode{\placeholdernc{XREF}(A)} denote a unary class template \tcode{T} +\item \tcode{\placeholdernc{XREF}(A)} denote a unary alias template \tcode{T} such that \tcode{T} denotes the same type as \tcode{U} with the addition of \tcode{A}'s cv and reference qualifiers, for a non-reference cv-unqualified type \tcode{U}, @@ -17260,17 +18337,18 @@ forms the logical conjunction of its template type arguments. \pnum -For a specialization \tcode{conjunction}, -if there is a template type argument \tcode{Bi} for which \tcode{bool(Bi::value)} is \tcode{false}, -then instantiating \tcode{conjunction::value} -does not require the instantiation of \tcode{Bj::value} for \tcode{j > i}. +For a specialization \tcode{conjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>}, +if there is a template type argument $\tcode{B}_{i}$ +for which \tcode{bool($\tcode{B}_{i}$::value)} is \tcode{false}, +then instantiating \tcode{conjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>::value} +does not require the instantiation of \tcode{$\tcode{B}_{j}$::value} for $j > i$. \begin{note} This is analogous to the short-circuiting behavior of the built-in operator \tcode{\&\&}. \end{note} \pnum Every template type argument -for which \tcode{Bi::value} is instantiated +for which \tcode{$\tcode{B}_{i}$::value} is instantiated shall be usable as a base class and shall have a member \tcode{value} which is convertible to \tcode{bool}, @@ -17278,14 +18356,14 @@ is unambiguously available in the type. \pnum -The specialization \tcode{conjunction} +The specialization \tcode{conjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>} has a public and unambiguous base that is either \begin{itemize} \item -the first type \tcode{Bi} in the list \tcode{true_type, B1, ..., BN} -for which \tcode{bool(Bi::value)} is \tcode{false}, or +the first type $\tcode{B}_{i}$ in the list \tcode{true_type, $\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$} +for which \tcode{bool($\tcode{B}_{i}$::value)} is \tcode{false}, or \item -if there is no such \tcode{Bi}, the last type in the list. +if there is no such $\tcode{B}_{i}$, the last type in the list. \end{itemize} \begin{note} This means a specialization of \tcode{conjunction} does not necessarily inherit from @@ -17309,17 +18387,18 @@ forms the logical disjunction of its template type arguments. \pnum -For a specialization \tcode{disjunction}, -if there is a template type argument \tcode{Bi} for which \tcode{bool(Bi::value)} is \tcode{true}, -then instantiating \tcode{disjunction::value} -does not require the instantiation of \tcode{Bj::value} for \tcode{j > i}. +For a specialization \tcode{disjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>}, +if there is a template type argument $\tcode{B}_{i}$ +for which \tcode{bool($\tcode{B}_{i}$::value)} is \tcode{true}, +then instantiating \tcode{disjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>::value} +does not require the instantiation of \tcode{$\tcode{B}_{j}$::value} for $j > i$. \begin{note} This is analogous to the short-circuiting behavior of the built-in operator \tcode{||}. \end{note} \pnum Every template type argument -for which \tcode{Bi::value} is instantiated +for which \tcode{$\tcode{B}_{i}$::value} is instantiated shall be usable as a base class and shall have a member \tcode{value} which is convertible to \tcode{bool}, @@ -17327,12 +18406,12 @@ is unambiguously available in the type. \pnum -The specialization \tcode{disjunction} +The specialization \tcode{disjunction<$\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$>} has a public and unambiguous base that is either \begin{itemize} -\item the first type \tcode{Bi} in the list \tcode{false_type, B1, ..., BN} -for which \tcode{bool(Bi::value)} is \tcode{true}, or -\item if there is no such \tcode{Bi}, the last type in the list. +\item the first type $\tcode{B}_{i}$ in the list \tcode{false_type, $\tcode{B}_{1}$, $\dotsc$, $\tcode{B}_{N}$} +for which \tcode{bool($\tcode{B}_{i}$::value)} is \tcode{true}, or +\item if there is no such $\tcode{B}_{i}$, the last type in the list. \end{itemize} \begin{note} This means a specialization of \tcode{disjunction} does not necessarily inherit from @@ -17394,6 +18473,31 @@ to either \tcode{endian::big} or \tcode{endian::little}. \end{itemdescr} +\rSec2[meta.const.eval]{Constant evaluation context} +\begin{itemdecl} +constexpr bool is_constant_evaluation() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{true} if and only if evaluation of the call occurs +within the evaluation of an expression or conversion +that is manifestly constant-evaluated\iref{expr.const}. + +\pnum +\begin{example} +\begin{codeblock} +constexpr void f(unsigned char *p, int n) { + if (std::is_constant_evaluated()) { // should not be a constexpr if statement + for (int k = 0; k}{string.cmp} +\movedxref{string.op<=}{string.cmp} +\movedxref{string.op>=}{string.cmp} + +\movedxref{istream::sentry}{istream.sentry} +\movedxref{ostream::sentry}{ostream.sentry} +\movedxref{ios::failure}{ios.failure} +\movedxref{ios::fmtflatgs}{ios.fmtflags} +\movedxref{ios::iostate}{ios.iostate} +\movedxref{ios::openmode}{ios.openmode} +\movedxref{ios::seekdir}{ios.seekdir} +\movedxref{ios::Init}{ios.init} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)