diff --git a/.travis.yml b/.travis.yml index 59d220bed8..47c6184ec9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,9 @@ # env: - - BUILD_TYPE=latexmk # build using latexmk + - BUILD_TYPE=latexmk # build using latexmk, also check for overfull hboxes - BUILD_TYPE=make # build using Makefile - - BUILD_TYPE=manual # build manually - - BUILD_TYPE=complete # build manually and regenerate figures, grammer, and cross-references + - BUILD_TYPE=complete # build manually and regenerate figures, grammar, and cross-references - BUILD_TYPE=check-whitespace # check for whitespace at the ends of lines script: @@ -14,6 +13,7 @@ script: - pushd source - if [ "$BUILD_TYPE" = "latexmk" ]; then latexmk -pdf std; + ! grep -Fe "Overfull \\hbox" std.log; fi - if [ "$BUILD_TYPE" = "make" ]; then make -j2; @@ -22,8 +22,6 @@ script: for FIGURE in *.dot; do dot -o$(basename $FIGURE .dot).pdf -Tpdf $FIGURE; done; - fi - - if [ "$BUILD_TYPE" = "manual" -o "$BUILD_TYPE" = "complete" ]; then pdflatex std; pdflatex std; pdflatex std; diff --git a/README.rst b/README.rst index 162aefdca4..3d61cca030 100644 --- a/README.rst +++ b/README.rst @@ -42,6 +42,15 @@ Install the following packages: dnf install texlive texlive-isodate texlive-relsize texlive-ulem texlive-fixme texlive-extract +----------------------------- +Getting Started on Arch Linux +----------------------------- + +Install the following packages: + + latex-mk from the Arch User Repository. + pacman -S texlive-latexextra + ------------ Instructions ------------ diff --git a/papers/n4713.pdf b/papers/n4713.pdf new file mode 100644 index 0000000000..254570829e Binary files /dev/null and b/papers/n4713.pdf differ diff --git a/papers/n4714.html b/papers/n4714.html new file mode 100644 index 0000000000..c3a2d132d1 --- /dev/null +++ b/papers/n4714.html @@ -0,0 +1,732 @@ +N4714 +

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

+ +

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

+ +

Acknowledgements

+ +

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

+ +

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

+ +

New papers

+ + + +

Motions incorporated into working draft

+ +

Core working group motions

+ +

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

+ + + +

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

+ + + +

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

+ +

CWG motion 4: P0588R1 "Simplifying implicit lambda capture"

+ +

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

+ +

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

+ + + +

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

+ + + +

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

+ +

CWG motion 9: P0857R0 "Functionality gaps in constraints"

+ +

CWG motion 10: P0692R1 "Access checking on specializations"

+ +

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

+ +

CWG motion 12: P0767R1 "Deprecate POD"

+ +

CWG motion 13: P0315R4 "Lambdas in unevaluated contexts"

+ +

Library working group motions

+ +

LWG motion 1 and 2 apply to the Parallelism TS.

+ +

LWG motion 3 applies to the Networking TS.

+ +

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

+ + + +

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

+ + + +

LWG motion 6: P0550R2 "Transformation trait remove_cvref"

+ +

LWG motion 7: P0777R1 "Treating unnecessary decay"

+ +

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

+ +

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

+ +

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

+ +

LWG motion 11: P0053R7 "Synchronized buffered ostream"

+ +

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

+ +

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

+ +

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

+ +

LWG motion 15: P0718R2 "Atomic shared_ptr"

+ +

LWG motion 16: P0020R6 "Floating point atomic"

+ +

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

+ +

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

+ +

Notable editorial changes

+ +

CWG motion 8

+ +

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

+ +

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

+ +

LWG motion 8

+ +

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

+ +

LWG motion 10

+ +

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

+ +

LWG motion 11

+ +

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

+ +

LWG motion 12

+ +

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

+ +

Text reorganization

+ +

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

+ + + +

Changes in the style of specification

+ + + +

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

+ +

Index of library headers

+ +

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

+ +

Minor editorial fixes

+ +

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

+ +
commit 903df06f3e67c9a52539892cb6844b55392c5331
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 27 22:00:03 2017 +0000
+
+    [allocator.adaptor.syn] Delete duplicate declarations of relational operators
+
+commit cebfe0a09fb56ec33726559c8b6d006dc19e4ab7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 15 23:18:22 2017 +0100
+
+    [temp.constr.order] In definition of 'subsumes', remove
+    confusing introductory paragraph.
+
+commit 74df95e9e3fad1aa5844c281614bbfffb1cc6189
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 22 23:45:18 2017 +0100
+
+    [diff] Introduce numbered paragraphs
+
+commit e543af304e195ad301da272caa7ef12107077ac0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 00:01:36 2017 +0100
+
+    [lib] Harmonize spacing for template headers.
+
+    Use 'template<class T>'.
+    Also remove space between two closing template brackets.
+
+commit b73e56f7a2b92449d9ec4938b01fa7014edad33a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 15 23:26:11 2017 +0100
+
+    [basic.link] Entities declared in an unnamed namespace
+    never have external linkage.
+
+commit fc16d3133817701a780092cf6456722a40e27d28
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 19 23:11:51 2017 +0100
+
+    [temp.arg.explicit] Remove note obsoleted by P0846R0
+
+commit d29bd8c6591fe74b095e5bd277f986462ba40b24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 26 18:36:42 2017 +0100
+
+    [fs.op.funcs] Separate effects from returns. (#1848)
+
+commit e2457df32a6ee70417681de10be78eb815a0b22f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 20 10:23:18 2017 +0100
+
+    [complex.numbers] Use \xref for references to the C standard.
+
+commit bd2ce5c2d4ec26a5c412160ce5983149c510a131
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 23:35:02 2017 +0100
+
+    Create a new index for library headers
+
+    and remove them from the index of library names.
+
+commit d1125303456c2305a72baebbb51d80151722f8ab
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 23 14:33:32 2017 +0000
+
+    [basic.life],[mem.res.private],[mem.res.pool.mem],[mem.res.monotonic.buffer] fix cross-references
+
+commit 1d467a8a06cabd314e250a04ca9a4c81591d035a
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Nov 23 15:31:45 2017 -0400
+
+    [func.require] Clarify which assignment operators
+
+commit 9dbbf9cbbe6994f7d4ad19098029e995eb34e1c3
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Nov 25 19:04:08 2017 -0400
+
+    [unord.req, fs.path.io] Fix "Effects: Equivalent to" styles (#1806)
+
+commit efdda2b9ca7f0ed78d7f134d8b1ca2e405610190
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 22:57:08 2017 +0100
+
+    [lib] Harmonize punctuation of 'Effects: Equivalent to' (#1815)
+
+commit 63ccd0513f6d9ac3555ca8becfcd7d15ed503522
+Author: stbergmann <sbergman@redhat.com>
+Date:   Sat Nov 25 03:33:31 2017 +0100
+
+    [basic.types] Add missing "be" in note (#1839)
+
+commit 9a8f4fde487200bcf4433facb0274f67d540617c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 03:29:09 2017 +0100
+
+    [lex.ccon] Align char16_t phrasing to UTF-8 one (#1847)
+
+commit 784f8c9980a74393ceaf201b343aa232a82113a4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 24 01:03:52 2017 +0000
+
+    [complex{,.special,.members}] Use injected-class-name in class definitions and itemdecls
+
+commit 877918fdc3e5223006b782d3c5959470bd7c02a8
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Nov 24 00:57:49 2017 +0000
+
+    [allocator.requirements] Fix pointer_to expression and reinstate descriptive variable 'r' (#1656)
+
+commit 2ca4340d93ec4cd63c330303e5beef20db8604df
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Nov 23 22:48:22 2017 +0000
+
+    [vector.bool] Use injected-class-name in synopsis (#1844)
+
+commit 4eedcb0d29f7c3b143dc3492caecb9c608590e12
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 22 19:26:28 2017 -0800
+
+    [diff.cpp17.library] Add Annex C entry for new headers <compare> and
+    <syncstream> added since C++17.
+
+commit 9112c6aecc48e1a0deea1f9493de224a43689a87
+Author: Aaron Ballman <aballman@grammatech.com>
+Date:   Mon Mar 13 09:51:35 2017 -0400
+
+    Use the terms "single-object delete expression" and
+    "array delete expression" as definitions, removing
+    the italics when not appropriate.
+
+commit b3b8a19812829ab521958eed6b2f1a3411180cdb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 19 22:17:17 2017 +0000
+
+    [structure.summary] Remove obsolete paragraph about Note(s): and Example(s): elements that we no longer provide
+
+    Also restyle a manual Note: in [unord.req] to use the standard note environment.
+
+commit 8958e953fd2cd60bd02ed4fcd2c055eded6e0f4d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 23:28:52 2017 +0000
+
+    [unord.req] Spell out the behaviour of cbegin/cend, remove ambiguous note
+
+commit b64354a7503c1cdc358d7f5dd1405ed903e170ef
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 22 12:10:00 2017 +0000
+
+    [depr.meta.types] Merge POD deprecation into existing type traits deprecation section and reorganize the section a bit
+
+commit 374252a76008ac0316320d2dd4e8652910539a97
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 22 01:01:39 2017 +0100
+
+    [util.sharedptr] Dissolve subclause and integrate contents into parent. (#1814)
+
+commit 75c0adccb38301f66979cc3c3ab5cd15a0a75a17
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 23:29:05 2017 +0100
+
+    [expr, over] Add cross-references for 'usual arithmetic conversions'. (#1804)
+
+commit 7670c1a8e025aa464fe5bebff7ae2626fb01b07f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 7 11:10:48 2017 +0100
+
+    [structure.specifications] Do not use library description macros in running text
+
+    This avoids colons in running text and some bad spacing.
+
+commit deb9fb19a039dbcd943a5955064d8c0e3d55a45c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Mar 4 06:46:30 2017 -1000
+
+    Consistent comma after e.g. and i.e.
+
+    After grepping to determine the preferred idiom, it seems clear that
+    the standard prefers to follow both e.g. and i.e. with a comma, rather
+    than omit it.  This patch applies that rule to the few places that
+    were missing the comma.
+
+commit e1b92d6c125ef43e19915ba0b031baa2c6611c62
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 18:01:18 2017 +0000
+
+    [over.match.best] Remove meaningless "i.e."
+
+commit 72b80b32c7ab185cc08eb72cf24ce6d839f7e6f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 16:19:36 2017 +0000
+
+    [alg.partition] Use established terminology 'partitioned with respect to'
+
+commit b4a1e3c1c73531f3a61ae6e44abecab766e9c537
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 15:52:31 2017 +0000
+
+    [binary.search] Formulate partitioning requirements in the same style as all the other related algorithms do
+
+commit b1fd50580cf389c61635a5767bf46b1b8823ce0c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 13:04:27 2017 +0100
+
+    [expr.compound] Expression operators do not 'return' results. (#1818)
+
+commit 68e53321ed7bf8505748e0f69947e21f9374d3a2
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Nov 21 08:02:52 2017 -0400
+
+    [strings.general] Use plural "string classes" (#1823)
+
+    The summary even says "string classes", and now we also have the "string_view classes".
+
+commit a5c25539b2605d8e6817b43d48e359d24642d1b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 11:46:26 2017 +0100
+
+    [variant] Move 'Otherwise' to start of following bullet. (#1813)
+
+commit e13e3097e6c92f67b86458af9a3d4793b0aeb544
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 01:49:37 2017 +0000
+
+    [utilities] Add missing charconv entry to summary table
+
+commit cbd25c4b3e6f83aaf2fa9fe894ff52b1f428a8c5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 12 00:37:09 2017 -0700
+
+    Hyphenate 'pointer-to-member' when it is an adjective and define the adjective.
+
+    Fixes #1369.
+
+commit 801fb0ba013362cede5a9eaeae0da688e554d3ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 06:51:19 2017 +0100
+
+    [conv.rank] Move from [conv] to [basic.types] (#1802)
+
+commit ff65cec7b977db1a6900b0321f10c91e152ab8d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 1 23:39:21 2017 +0100
+
+    Use 'trailing requires-clause'
+
+    where the requires-clause in a template-head is not meant.
+
+    Fixes #1672.
+
+commit 672bb6075cb0512a234b4f6bdd41f00cc01e6642
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 19 23:03:42 2017 +0200
+
+    [dcl.init] Clarify introduction
+
+    Fixes #1615.
+
+commit 7c6f936298543387f2f17563f01e95fce904783d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 2 22:18:04 2017 +0100
+
+    [array] Dissolve single-item subclauses.
+
+    Partially addresses #1242.
+
+commit 04c4e8338eadb18deb63354a95c2624ef5b3fbed
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 19:34:18 2017 +0100
+
+    [intro.execution] Clarify full-expression in example.
+
+    Fixes #1706.
+
+commit 2e25955ecf6a576c98590097ec76aa616495c466
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 07:29:23 2017 +0100
+
+    [expr] Add subclauses and adjust cross-references to [expr].
+
+    Also move [basic.lval] into [expr].
+
+commit 87c88e99620ecbc3958dc0e06d86aa72806206c4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Nov 11 21:48:25 2017 -0700
+
+    [algorithms.general] & [algorithm.syn] name "mutating sequence operations" consistently (#1801)
+
+    Despite the stable name "alg.modifying.operations," the section is titled "Mutating sequence operations."
+
+commit 0963b3d26dcce7dff2b924e4d9d3daff0e1f50d6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 05:32:46 2017 +0100
+
+    [lib] Harmonize introductory comments in synopses (#1775)
+
+    Even if no section reference is given, make them lowercase
+    and remove trailing colons.
+
+commit 6b6578cc415bf17b237a0889ef2dc53f4b392d02
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 05:30:40 2017 +0100
+
+    [locale.moneypunct.virtuals] Add reference to ISO 4217. (#1779)
+
+commit 49870469d0a3347b91e42faa9c931859e924e83e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 04:21:40 2017 +0100
+
+    [lib] Add hyphen to 'well-defined' (#1776)
+
+commit 982a456f176ca00409c6e514af932051dce2485f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 05:06:58 2017 +0100
+
+    [intro], [basic] Rearrange subclauses
+
+    Fixes #1539.
+
+commit 301a71e35c49fafe2188736aff2631f36c81dd47
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 10 23:55:37 2017 -0800
+
+    [basic.lookup.argdep] Correct xref to point to the normative invisible
+    friend rule.
+
+commit 4f77c89e7635c8a9f361a0757c7765bcefeacd5e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 9 17:33:33 2017 -0700
+
+    [over.built] Improve placeholder phrasing
+
+commit 24bfe67b857bc6634ffc796324999373352d6d72
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 8 23:50:33 2017 -0700
+
+    [meta.endian] Clarify wording regarding size of scalar types
+
+commit 7a7d123584613a90cc64dbfb4b848807c3f085c8
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Nov 8 01:50:47 2017 -0400
+
+    [any.class] Revert dot to comma typo from bdff8687c (#1795)
+
+commit ee8aa525e65ada1f1949ebc9eb006af8b29f7e85
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 8 00:13:27 2017 +0000
+
+    [basic.ios.members], [streambuf.virt.put], [cmplx.over] replace enumerated lists with itemized
+
+commit 6ca5523589f8eb8d2843fe34386382a34064f41d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Nov 7 23:24:36 2017 +0000
+
+    [fstream], [fs.class.directory_entry] qualify filesystem::path consistently
+
+commit b4acb0ca022f5b4e8a535a164c845ab87e312a1f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Nov 7 08:56:03 2017 -0800
+
+    [basic.def] Fix typo "braced-enclosed".
+
+commit b174bd63680803b18f1ebce4d743b13c257cd3bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 2 18:54:45 2017 +0000
+
+    [defns.referenceable] Remove duplicate 'an'
+
+commit f0b892320c609974270ccd415ecef081529e664f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 2 03:19:54 2017 +0100
+
+    [array.size] Remove full member declaration from itemdecl. (#1790)
+
+commit ea4b17a448b46671488b96812629d92c0c9c61be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 27 00:53:45 2017 +0200
+
+    [expr.prim.lambda.capture] Move discusssion of capture-by-reference of references
+
+    to after the introduction of 'capture by reference'.
+
+    Fixes #1785.
+
diff --git a/papers/n4714.md b/papers/n4714.md new file mode 100644 index 0000000000..3d220ec6e4 --- /dev/null +++ b/papers/n4714.md @@ -0,0 +1,591 @@ +# N4714 Editors' Report -- Programming Languages -- C++ + +2017-11-27 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4700. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4713](http://wg21.link/n4713) is the current working draft for C++20. It replaces [N4700](http://wg21.link/n4700). + * N4714 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolution](http://wg21.link/p0817r0) for 1 issue in "ready" status applied: + + * [2342](http://wg21.link/cwg2342) Reference `reinterpret_cast` and pointer-interconvertibility + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0818r1) for 7 issues in "tentatively ready" status applied: + + * [1862](http://wg21.link/cwg1862) Determining "corresponding members" for friendship + * [2177](http://wg21.link/cwg2177) Placement `operator delete` and parameter copies + * [2305](http://wg21.link/cwg2305) Explicit instantiation of `constexpr` or `inline` variable template + * [2307](http://wg21.link/cwg2307) Unclear definition of "equivalent to a nontype template parameter" + * [2313](http://wg21.link/cwg2313) Redeclaration of structured binding reference variables + * [2315](http://wg21.link/cwg2315) What is the "corresponding special member" of a variant member? + * [2338](http://wg21.link/cwg2338) Undefined behavior converting to short enums with fixed underlying types + +CWG motion 3: [P0614R1 "Range-based `for` statements with initializer"](http://wg21.link/p0614r1) + +CWG motion 4: [P0588R1 "Simplifying implicit lambda capture"](http://wg21.link/p0588r1) + +CWG motion 5: [P0846R0 "ADL and function templates that are not visible"](http://wg21.link/p0846r0) + +CWG motion 6: [P0641R2 "Resolving core issue #1331"](http://wg21.link/p0641r2), resolving 1 core issue: + + * [1331](http://wg21.link/cwg1331) `const` mismatch with defaulted copy constructor + +CWG motion 7: [P0859R0 "Core issue 1581"](http://wg21.link/p0859r0), resolving 1 core issue: + + * [1581](http://wg21.link/cwg1581) When are `constexpr` member functions defined? + +CWG motion 8: [P0515R3 "Consistent comparison"](http://wg21.link/p0515r3) and [P0768R1 "Library support for the spaceship (comparison) operator"](http://wg21.link/p0768r1) + +CWG motion 9: [P0857R0 "Functionality gaps in constraints"](http://wg21.link/p0857r0) + +CWG motion 10: [P0692R1 "Access checking on specializations"](http://wg21.link/p0692r1) + +CWG motion 11: [P0624R2 "Default constructible and assignable stateless lambdas"](http://wg21.link/p0624r2) + +CWG motion 12: [P0767R1 "Deprecate POD"](http://wg21.link/p0767r1) + +CWG motion 13: [P0315R4 "Lambdas in unevaluated contexts"](http://wg21.link/p0315r4) + +### Library working group motions + +LWG motion 1 and 2 apply to the Parallelism TS. + +LWG motion 3 applies to the Networking TS. + +LWG motion 4: [Library issue resolutions](http://wg21.link/p0815r0) for 24 issues in "Ready" or "Tentatively Ready" status applied: + + * [2870](http://wg21.link/lwg2870) Default value of parameter `theta` of `polar` should be dependent + * [2935](http://wg21.link/lwg2935) What should `create_directories` do when `p` already exists but is not a directory? + * [2941](http://wg21.link/lwg2941) [thread.req.timing] wording should apply to both member and namespace-level functions + * [2944](http://wg21.link/lwg2944) [LWG 2905](http://wg21.link/lwg2905) accidentally removed requirement that construction of the deleter doesn't throw an exception + * [2945](http://wg21.link/lwg2945) Order of template parameters in `optional` comparisons + * [2948](http://wg21.link/lwg2948) `unique_ptr` does not define `operator<<` for stream output + * [2950](http://wg21.link/lwg2950) `std::byte` operations are misspecified + * [2952](http://wg21.link/lwg2952) `iterator_traits` should work for pointers to *cv* `T` + * [2953](http://wg21.link/lwg2953) [LWG 2853](http://wg21.link/lwg2853) should apply to `deque::erase` too + * [2964](http://wg21.link/lwg2964) Apparently redundant requirement for `dynamic_pointer_cast` + * [2965](http://wg21.link/lwg2965) Non-existing `path::native_string()` in `filesystem_error::what()` specification + * [2972](http://wg21.link/lwg2972) What is `is_trivially_destructible_v`? + * [2976](http://wg21.link/lwg2976) Dangling `uses_allocator` specialization for `packaged_task` + * [2977](http://wg21.link/lwg2977) `unordered_`*meow*`::merge()` has incorrect **Throws:** clause + * [2978](http://wg21.link/lwg2978) Hash support for `pmr::string` and friends + * [2979](http://wg21.link/lwg2979) `aligned_union` should require complete object types + * [2980](http://wg21.link/lwg2980) Cannot `compare_exchange` empty pointers + * [2981](http://wg21.link/lwg2981) Remove redundant deduction guides from standard library + * [2982](http://wg21.link/lwg2982) Making `size_type` consistent in associative container deduction guides + * [2988](http://wg21.link/lwg2988) Clause 32 cleanup missed one `typename` + * [2993](http://wg21.link/lwg2993) `reference_wrapper` conversion from `T&&` + * [2998](http://wg21.link/lwg2998) Requirements on function objects passed to {`forward_`,}`list`-specific algorithms + * [3001](http://wg21.link/lwg3001) `weak_ptr::element_type` needs `remove_extent_t` + * [3024](http://wg21.link/lwg3024) `variant`'s copies must be deleted instead of disabled via SFINAE + +LWG motion 5: [Library issue resolution](http://wg21.link/p0864r0) for 1 issue in "Immediate" status applied: + + * [2958](http://wg21.link/2958) Moves improperly defined as deleted + +LWG motion 6: [P0550R2 "Transformation trait `remove_cvref`"](http://wg21.link/p0550r2) + +LWG motion 7: [P0777R1 "Treating unnecessary `decay`"](http://wg21.link/p0777r1) + +LWG motion 8: [P0600R1 "`[[nodiscard]]` in the Library"](http://wg21.link/p0600r1) + +Do not try and apply LWG motion 9 to the working draft. That's impossible. +Instead, only realize the truth. There is no LWG motion 9. + +LWG motion 10: [P0439R0 "Make `std::memory_order` a scoped enumeration"](http://wg21.link/p0439r0) + +LWG motion 11: [P0053R7 "Synchronized buffered `ostream`"](http://wg21.link/p0053r7) + +LWG motion 12: [P0653R2 "Utility to convert a pointer to a raw pointer"](http://wg21.link/p0653r2) + +LWG motion 13: [P0202R3 "Add `constexpr` modifiers to functions in `` and `` Headers"](http://wg21.link/p0202r3) + +LWG motion 14: [P0415R1 "`constexpr` for `std::complex`"](http://wg21.link/p0415r1) + +LWG motion 15: [P0718R2 "Atomic `shared_ptr`"](http://wg21.link/p0718r2) + +LWG motion 16: [P0020R6 "Floating point atomic"](http://wg21.link/p0020r6) + +LWG motion 17: [P0616R0 "De-pessimize legacy `` algorithms with `std::move`"](http://wg21.link/p0616r0) + +LWG motion 18: [P0457R2 "String prefix and suffix checking"](http://wg21.link/p0457r2) + +## Notable editorial changes + +### CWG motion 8 + +Instead of removing [operators] and adding a new section to [requirements], the +existing stable name for this section is preserved. This section was moved to +[description] rather than to [requirements], as it describes a notational +device used for standard exposition. + +[alg.3way] added to [alg.sorting] rather than [alg.nonmodifying] to +match existing `lexicographical_compare` functions. + +### LWG motion 8 + +`[[nodiscard]]` was inadvertantly omitted from `deque::empty()` in the detailed +wording changes (but was covered by the general description of the change). +After consultation with LWG, this oversight has been corrected in the wording. + +### LWG motion 10 + +All references to the existing `memory_order_*` enumerators throughout the +working draft were updated to use the new scoped enumerator nmaes. + +### LWG motion 11 + +Changes were made to the organization and presentation of the wording +to fit better into the existing document. + +### LWG motion 12 + +The requested addition to [pointer.traits.function] has been moved into a new +subclause "Pointer traits optional members" and modified slightly to fit this +new presentation, as it does not describe a member of the `pointer_traits` +primary template. + +### Text reorganization + +In an effort to conform to ISO drafting directives to avoid hanging paragraphs +(text in subclauses that also contain further nested subclauses) and to remove +excessive subclause structure, the following changes have been made: + +* [intro] and [basic] have been reorganized so that [intro] acts as an + introduction to the standard document and [basic] introduces the basic + concepts of the standard in an order closer to dependency order +* [conv.rank] moved from [conv] to [basic.types], as it does not describe a conversion. +* [expr] has additional subclause structure to partially resolve hanging + paragraphs and generally improve its organization +* [expr] has a new subclause describing properties of expressions, containing + some of the prior hanging paragraphs from [expr], as well as [basic.lval] +* [array], [util.sharedptr] Per-function subclauses have been merged into parent subclause. + +### Changes in the style of specification + +* Code font is no longer used when referring to non-syntax properties of entities + (even when those properties are derived from syntax). This applies to the terms + "inline", "friend", "public", "protected", "private", "const object". + We generally intend to use code font only when referring specifically + to program syntax. + +* In library wording, template headers are formatted consistently with no + space between the `template` keyword and the `<` token. + +Drafting for future standard changes should take the above into account. + +### Index of library headers + +In order to keep the "Index of library names" focused on listing library names, +index entries for library headers have been moved to a separate, new "Index of +library headers". + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4700 is below. +This list excludes changes +that do not affect the body text or only affect whitespace or typeface. For a +complete list including such changes (or for the actual deltas applied by these +changes), consult the [draft sources on github](https://github.com/cplusplus/draft/compare/n4700...n4713). + + commit 903df06f3e67c9a52539892cb6844b55392c5331 + Author: Thomas Köppe + Date: Mon Nov 27 22:00:03 2017 +0000 + + [allocator.adaptor.syn] Delete duplicate declarations of relational operators + + commit cebfe0a09fb56ec33726559c8b6d006dc19e4ab7 + Author: Jens Maurer + Date: Wed Nov 15 23:18:22 2017 +0100 + + [temp.constr.order] In definition of 'subsumes', remove + confusing introductory paragraph. + + commit 74df95e9e3fad1aa5844c281614bbfffb1cc6189 + Author: Jens Maurer + Date: Wed Nov 22 23:45:18 2017 +0100 + + [diff] Introduce numbered paragraphs + + commit e543af304e195ad301da272caa7ef12107077ac0 + Author: Jens Maurer + Date: Sat Nov 25 00:01:36 2017 +0100 + + [lib] Harmonize spacing for template headers. + + Use 'template'. + Also remove space between two closing template brackets. + + commit b73e56f7a2b92449d9ec4938b01fa7014edad33a + Author: Jens Maurer + Date: Wed Nov 15 23:26:11 2017 +0100 + + [basic.link] Entities declared in an unnamed namespace + never have external linkage. + + commit fc16d3133817701a780092cf6456722a40e27d28 + Author: Jens Maurer + Date: Sun Nov 19 23:11:51 2017 +0100 + + [temp.arg.explicit] Remove note obsoleted by P0846R0 + + commit d29bd8c6591fe74b095e5bd277f986462ba40b24 + Author: Jens Maurer + Date: Sun Nov 26 18:36:42 2017 +0100 + + [fs.op.funcs] Separate effects from returns. (#1848) + + commit e2457df32a6ee70417681de10be78eb815a0b22f + Author: Jens Maurer + Date: Mon Nov 20 10:23:18 2017 +0100 + + [complex.numbers] Use \xref for references to the C standard. + + commit bd2ce5c2d4ec26a5c412160ce5983149c510a131 + Author: Jens Maurer + Date: Tue Nov 21 23:35:02 2017 +0100 + + Create a new index for library headers + + and remove them from the index of library names. + + commit d1125303456c2305a72baebbb51d80151722f8ab + Author: Jonathan Wakely + Date: Thu Nov 23 14:33:32 2017 +0000 + + [basic.life],[mem.res.private],[mem.res.pool.mem],[mem.res.monotonic.buffer] fix cross-references + + commit 1d467a8a06cabd314e250a04ca9a4c81591d035a + Author: Johel Ernesto Guerrero Peña + Date: Thu Nov 23 15:31:45 2017 -0400 + + [func.require] Clarify which assignment operators + + commit 9dbbf9cbbe6994f7d4ad19098029e995eb34e1c3 + Author: Johel Ernesto Guerrero Peña + Date: Sat Nov 25 19:04:08 2017 -0400 + + [unord.req, fs.path.io] Fix "Effects: Equivalent to" styles (#1806) + + commit efdda2b9ca7f0ed78d7f134d8b1ca2e405610190 + Author: Jens Maurer + Date: Sat Nov 25 22:57:08 2017 +0100 + + [lib] Harmonize punctuation of 'Effects: Equivalent to' (#1815) + + commit 63ccd0513f6d9ac3555ca8becfcd7d15ed503522 + Author: stbergmann + Date: Sat Nov 25 03:33:31 2017 +0100 + + [basic.types] Add missing "be" in note (#1839) + + commit 9a8f4fde487200bcf4433facb0274f67d540617c + Author: Jens Maurer + Date: Sat Nov 25 03:29:09 2017 +0100 + + [lex.ccon] Align char16_t phrasing to UTF-8 one (#1847) + + commit 784f8c9980a74393ceaf201b343aa232a82113a4 + Author: Thomas Köppe + Date: Fri Nov 24 01:03:52 2017 +0000 + + [complex{,.special,.members}] Use injected-class-name in class definitions and itemdecls + + commit 877918fdc3e5223006b782d3c5959470bd7c02a8 + Author: Jonathan Wakely + Date: Fri Nov 24 00:57:49 2017 +0000 + + [allocator.requirements] Fix pointer_to expression and reinstate descriptive variable 'r' (#1656) + + commit 2ca4340d93ec4cd63c330303e5beef20db8604df + Author: Jonathan Wakely + Date: Thu Nov 23 22:48:22 2017 +0000 + + [vector.bool] Use injected-class-name in synopsis (#1844) + + commit 4eedcb0d29f7c3b143dc3492caecb9c608590e12 + Author: Richard Smith + Date: Wed Nov 22 19:26:28 2017 -0800 + + [diff.cpp17.library] Add Annex C entry for new headers and + added since C++17. + + commit 9112c6aecc48e1a0deea1f9493de224a43689a87 + Author: Aaron Ballman + Date: Mon Mar 13 09:51:35 2017 -0400 + + Use the terms "single-object delete expression" and + "array delete expression" as definitions, removing + the italics when not appropriate. + + commit b3b8a19812829ab521958eed6b2f1a3411180cdb + Author: Thomas Köppe + Date: Sun Nov 19 22:17:17 2017 +0000 + + [structure.summary] Remove obsolete paragraph about Note(s): and Example(s): elements that we no longer provide + + Also restyle a manual Note: in [unord.req] to use the standard note environment. + + commit 8958e953fd2cd60bd02ed4fcd2c055eded6e0f4d + Author: Thomas Köppe + Date: Tue Nov 21 23:28:52 2017 +0000 + + [unord.req] Spell out the behaviour of cbegin/cend, remove ambiguous note + + commit b64354a7503c1cdc358d7f5dd1405ed903e170ef + Author: Thomas Köppe + Date: Wed Nov 22 12:10:00 2017 +0000 + + [depr.meta.types] Merge POD deprecation into existing type traits deprecation section and reorganize the section a bit + + commit 374252a76008ac0316320d2dd4e8652910539a97 + Author: Jens Maurer + Date: Wed Nov 22 01:01:39 2017 +0100 + + [util.sharedptr] Dissolve subclause and integrate contents into parent. (#1814) + + commit 75c0adccb38301f66979cc3c3ab5cd15a0a75a17 + Author: Jens Maurer + Date: Tue Nov 21 23:29:05 2017 +0100 + + [expr, over] Add cross-references for 'usual arithmetic conversions'. (#1804) + + commit 7670c1a8e025aa464fe5bebff7ae2626fb01b07f + Author: Jens Maurer + Date: Tue Feb 7 11:10:48 2017 +0100 + + [structure.specifications] Do not use library description macros in running text + + This avoids colons in running text and some bad spacing. + + commit deb9fb19a039dbcd943a5955064d8c0e3d55a45c + Author: Alisdair Meredith + Date: Sat Mar 4 06:46:30 2017 -1000 + + Consistent comma after e.g. and i.e. + + After grepping to determine the preferred idiom, it seems clear that + the standard prefers to follow both e.g. and i.e. with a comma, rather + than omit it. This patch applies that rule to the few places that + were missing the comma. + + commit e1b92d6c125ef43e19915ba0b031baa2c6611c62 + Author: Thomas Köppe + Date: Tue Nov 21 18:01:18 2017 +0000 + + [over.match.best] Remove meaningless "i.e." + + commit 72b80b32c7ab185cc08eb72cf24ce6d839f7e6f3 + Author: Thomas Köppe + Date: Tue Nov 21 16:19:36 2017 +0000 + + [alg.partition] Use established terminology 'partitioned with respect to' + + commit b4a1e3c1c73531f3a61ae6e44abecab766e9c537 + Author: Thomas Köppe + Date: Tue Nov 21 15:52:31 2017 +0000 + + [binary.search] Formulate partitioning requirements in the same style as all the other related algorithms do + + commit b1fd50580cf389c61635a5767bf46b1b8823ce0c + Author: Jens Maurer + Date: Tue Nov 21 13:04:27 2017 +0100 + + [expr.compound] Expression operators do not 'return' results. (#1818) + + commit 68e53321ed7bf8505748e0f69947e21f9374d3a2 + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 21 08:02:52 2017 -0400 + + [strings.general] Use plural "string classes" (#1823) + + The summary even says "string classes", and now we also have the "string_view classes". + + commit a5c25539b2605d8e6817b43d48e359d24642d1b7 + Author: Jens Maurer + Date: Tue Nov 21 11:46:26 2017 +0100 + + [variant] Move 'Otherwise' to start of following bullet. (#1813) + + commit e13e3097e6c92f67b86458af9a3d4793b0aeb544 + Author: Thomas Köppe + Date: Tue Nov 21 01:49:37 2017 +0000 + + [utilities] Add missing charconv entry to summary table + + commit cbd25c4b3e6f83aaf2fa9fe894ff52b1f428a8c5 + Author: Thomas Köppe + Date: Sun Nov 12 00:37:09 2017 -0700 + + Hyphenate 'pointer-to-member' when it is an adjective and define the adjective. + + Fixes #1369. + + commit 801fb0ba013362cede5a9eaeae0da688e554d3ad + Author: Jens Maurer + Date: Sun Nov 12 06:51:19 2017 +0100 + + [conv.rank] Move from [conv] to [basic.types] (#1802) + + commit ff65cec7b977db1a6900b0321f10c91e152ab8d2 + Author: Jens Maurer + Date: Wed Nov 1 23:39:21 2017 +0100 + + Use 'trailing requires-clause' + + where the requires-clause in a template-head is not meant. + + Fixes #1672. + + commit 672bb6075cb0512a234b4f6bdd41f00cc01e6642 + Author: Jens Maurer + Date: Wed Apr 19 23:03:42 2017 +0200 + + [dcl.init] Clarify introduction + + Fixes #1615. + + commit 7c6f936298543387f2f17563f01e95fce904783d + Author: Jens Maurer + Date: Thu Nov 2 22:18:04 2017 +0100 + + [array] Dissolve single-item subclauses. + + Partially addresses #1242. + + commit 04c4e8338eadb18deb63354a95c2624ef5b3fbed + Author: Jens Maurer + Date: Sat Nov 11 19:34:18 2017 +0100 + + [intro.execution] Clarify full-expression in example. + + Fixes #1706. + + commit 2e25955ecf6a576c98590097ec76aa616495c466 + Author: Jens Maurer + Date: Sat Nov 11 07:29:23 2017 +0100 + + [expr] Add subclauses and adjust cross-references to [expr]. + + Also move [basic.lval] into [expr]. + + commit 87c88e99620ecbc3958dc0e06d86aa72806206c4 + Author: Casey Carter + Date: Sat Nov 11 21:48:25 2017 -0700 + + [algorithms.general] & [algorithm.syn] name "mutating sequence operations" consistently (#1801) + + Despite the stable name "alg.modifying.operations," the section is titled "Mutating sequence operations." + + commit 0963b3d26dcce7dff2b924e4d9d3daff0e1f50d6 + Author: Jens Maurer + Date: Sun Nov 12 05:32:46 2017 +0100 + + [lib] Harmonize introductory comments in synopses (#1775) + + Even if no section reference is given, make them lowercase + and remove trailing colons. + + commit 6b6578cc415bf17b237a0889ef2dc53f4b392d02 + Author: Jens Maurer + Date: Sun Nov 12 05:30:40 2017 +0100 + + [locale.moneypunct.virtuals] Add reference to ISO 4217. (#1779) + + commit 49870469d0a3347b91e42faa9c931859e924e83e + Author: Jens Maurer + Date: Sun Nov 12 04:21:40 2017 +0100 + + [lib] Add hyphen to 'well-defined' (#1776) + + commit 982a456f176ca00409c6e514af932051dce2485f + Author: Jens Maurer + Date: Sat Nov 11 05:06:58 2017 +0100 + + [intro], [basic] Rearrange subclauses + + Fixes #1539. + + commit 301a71e35c49fafe2188736aff2631f36c81dd47 + Author: Richard Smith + Date: Fri Nov 10 23:55:37 2017 -0800 + + [basic.lookup.argdep] Correct xref to point to the normative invisible + friend rule. + + commit 4f77c89e7635c8a9f361a0757c7765bcefeacd5e + Author: Thomas Köppe + Date: Thu Nov 9 17:33:33 2017 -0700 + + [over.built] Improve placeholder phrasing + + commit 24bfe67b857bc6634ffc796324999373352d6d72 + Author: Thomas Köppe + Date: Wed Nov 8 23:50:33 2017 -0700 + + [meta.endian] Clarify wording regarding size of scalar types + + commit 7a7d123584613a90cc64dbfb4b848807c3f085c8 + Author: Johel Ernesto Guerrero Peña + Date: Wed Nov 8 01:50:47 2017 -0400 + + [any.class] Revert dot to comma typo from bdff8687c (#1795) + + commit ee8aa525e65ada1f1949ebc9eb006af8b29f7e85 + Author: Jonathan Wakely + Date: Wed Nov 8 00:13:27 2017 +0000 + + [basic.ios.members], [streambuf.virt.put], [cmplx.over] replace enumerated lists with itemized + + commit 6ca5523589f8eb8d2843fe34386382a34064f41d + Author: Jonathan Wakely + Date: Tue Nov 7 23:24:36 2017 +0000 + + [fstream], [fs.class.directory_entry] qualify filesystem::path consistently + + commit b4acb0ca022f5b4e8a535a164c845ab87e312a1f + Author: Richard Smith + Date: Tue Nov 7 08:56:03 2017 -0800 + + [basic.def] Fix typo "braced-enclosed". + + commit b174bd63680803b18f1ebce4d743b13c257cd3bf + Author: Thomas Köppe + Date: Thu Nov 2 18:54:45 2017 +0000 + + [defns.referenceable] Remove duplicate 'an' + + commit f0b892320c609974270ccd415ecef081529e664f + Author: Jens Maurer + Date: Thu Nov 2 03:19:54 2017 +0100 + + [array.size] Remove full member declaration from itemdecl. (#1790) + + commit ea4b17a448b46671488b96812629d92c0c9c61be + Author: Jens Maurer + Date: Fri Oct 27 00:53:45 2017 +0200 + + [expr.prim.lambda.capture] Move discusssion of capture-by-reference of references + + to after the introduction of 'capture by reference'. + + Fixes #1785. diff --git a/source/Makefile b/source/Makefile index a3f9033b4b..62957b3d6a 100644 --- a/source/Makefile +++ b/source/Makefile @@ -38,10 +38,12 @@ reindex: $(STDPDF) $(STDPDF) makeindex generalindex + makeindex headerindex makeindex libraryindex makeindex grammarindex makeindex impldefindex makeindex -s basic.gst -o xrefindex.gls xrefindex.glo + makeindex -s basic.gst -o xrefdelta.gls xrefdelta.glo $(STDPDF) $(STDPDF) diff --git a/source/access.tex b/source/access.tex index d43b9f468e..c94a55d832 100644 --- a/source/access.tex +++ b/source/access.tex @@ -12,18 +12,18 @@ \begin{itemize} \item \indextext{access control!\idxcode{private}}% -\tcode{private}; +private; that is, its name can be used only by members and friends of the class in which it is declared. \item \indextext{access control!\idxcode{protected}}% -\tcode{protected}; +protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see~\ref{class.protected}). \item \indextext{access control!\idxcode{public}}% -\tcode{public}; +public; that is, its name can be used anywhere without access restriction. \end{itemize} @@ -44,12 +44,8 @@ \tcode{private} by default. Members of a class defined with the keywords -\tcode{struct} -or -\tcode{union} -are -\tcode{public} -by default. +\tcode{struct} or \tcode{union} +are public by default. \begin{example} \begin{codeblock} @@ -68,8 +64,7 @@ referred to from declarations or expressions. \begin{note} Access control applies to names nominated by -\tcode{friend} -declarations\iref{class.friend} and +friend declarations\iref{class.friend} and \grammarterm{using-declaration}{s}\iref{namespace.udecl}. \end{note} In the case of overloaded function names, access control is applied to @@ -200,7 +195,7 @@ (\ref{class.derived}): \begin{ncbnftab} -access-specifier \terminal{:} member-specification\opt +access-specifier \terminal{:} \opt{member-specification} \end{ncbnftab} An @@ -289,35 +284,23 @@ If a class is declared to be a base class\iref{class.derived} for another class using the \tcode{public} access specifier, the -\tcode{public} -members of the base class are accessible as -\tcode{public} -members of the derived class and -\tcode{protected} -members of the base class are accessible as -\tcode{protected} -members of the derived class. +public members of the base class are accessible as +public members of the derived class and +protected members of the base class are accessible as +protected members of the derived class. If a class is declared to be a base class for another class using the \tcode{protected} access specifier, the -\tcode{public} -and -\tcode{protected} -members of the base class are accessible as -\tcode{protected} -members of the derived class. +public and protected members of the base class are accessible as +protected members of the derived class. If a class is declared to be a base class for another class using the -\tcode{private} +private access specifier, the -\tcode{public} -and -\tcode{protected} -members of the base class are accessible as -\tcode{private} +public and protected +members of the base class are accessible as private members of the derived class.\footnote{As specified previously in \ref{class.access}, private members of a base class remain inaccessible even to derived classes -unless -\tcode{friend} +unless friend declarations within the base class definition are used to grant access explicitly.} \pnum @@ -673,7 +656,7 @@ \end{example} \pnum -A \tcode{friend} declaration that does not declare a function +A friend declaration that does not declare a function shall have one of the following forms: \begin{ncsimplebnf} @@ -682,12 +665,12 @@ \terminal{friend} typename-specifier \terminal{;} \end{ncsimplebnf} -\begin{note} A \tcode{friend} declaration may be the +\begin{note} A friend declaration may be the \term{declaration} in a \grammarterm{template-declaration} (\ref{temp}, \ref{temp.friend}).\end{note} If the type specifier in a \tcode{friend} declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the -\tcode{friend} declaration is ignored. \begin{example} +friend declaration is ignored. \begin{example} \begin{codeblock} class C; @@ -720,8 +703,7 @@ \pnum \indextext{declaration!overloaded name and \tcode{friend}}% -When a -\tcode{friend} +When a friend declaration refers to an overloaded name or operator, only the function specified by the parameter types becomes a friend. A member function of a class @@ -758,8 +740,7 @@ \pnum Such a function is implicitly an inline function\iref{dcl.inline}. -A -\tcode{friend} +A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not\iref{basic.lookup.unqual}. @@ -775,11 +756,7 @@ A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration. The meaning of the friend declaration is the same whether the friend declaration -appears in the -\tcode{private}, -\tcode{protected} -or -\tcode{public}\iref{class.mem} +appears in the private, protected, or public\iref{class.mem} portion of the class \grammarterm{member-specification}. diff --git a/source/algorithms.tex b/source/algorithms.tex index 7d3ea7f46e..5eee152e6a 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -4,13 +4,13 @@ \rSec1[algorithms.general]{General} \pnum -This Clause describes components that \Cpp programs may use to perform +This Clause describes components that \Cpp{} programs may use to perform algorithmic operations on containers\iref{containers} and other sequences. \pnum The following subclauses describe components for non-modifying sequence operations, -modifying sequence operations, +mutating sequence operations, sorting and related operations, and algorithms from the ISO C library, as summarized in Table~\ref{tab:algorithms.summary}. @@ -23,8 +23,7 @@ \end{libsumtab} \rSec1[algorithm.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{algorithm}}% -\indexlibrary{\idxhdr{algorithm}}% +\indexhdr{algorithm}% \begin{codeblock} #include @@ -32,56 +31,56 @@ namespace std { // \ref{alg.nonmodifying}, non-modifying sequence operations // \ref{alg.all_of}, all of - template - bool all_of(InputIterator first, InputIterator last, Predicate pred); - template + template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); + template bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); // \ref{alg.any_of}, any of - template - bool any_of(InputIterator first, InputIterator last, Predicate pred); - template + template + constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); + template bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); // \ref{alg.none_of}, none of - template - bool none_of(InputIterator first, InputIterator last, Predicate pred); - template + template + constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); + template bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); // \ref{alg.foreach}, for each template - Function for_each(InputIterator first, InputIterator last, Function f); + 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); template - InputIterator for_each_n(InputIterator first, Size n, Function f); + constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); template ForwardIterator for_each_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, Function f); // \ref{alg.find}, find template - InputIterator find(InputIterator first, InputIterator last, - const T& value); + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); template ForwardIterator find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template - InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); template ForwardIterator find_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); template - InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if_not(InputIterator first, InputIterator last, + Predicate pred); template ForwardIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, @@ -89,11 +88,11 @@ // \ref{alg.find.end}, find end template - ForwardIterator1 + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template - ForwardIterator1 + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -112,11 +111,11 @@ // \ref{alg.find.first.of}, find first template - InputIterator + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); template - InputIterator + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); @@ -135,53 +134,53 @@ // \ref{alg.adjacent.find}, adjacent find template - ForwardIterator adjacent_find(ForwardIterator first, - ForwardIterator last); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); template - ForwardIterator adjacent_find(ForwardIterator first, - ForwardIterator last, - BinaryPredicate pred); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); template - ForwardIterator adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, - ForwardIterator last); + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); template - ForwardIterator adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, - ForwardIterator last, - BinaryPredicate pred); + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); // \ref{alg.count}, count template - typename iterator_traits::difference_type + constexpr typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); template typename iterator_traits::difference_type count(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template - typename iterator_traits::difference_type + constexpr typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); template typename iterator_traits::difference_type count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); // \ref{mismatch}, mismatch template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); @@ -211,18 +210,18 @@ // \ref{alg.equal}, equal template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); template bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, @@ -245,108 +244,110 @@ // \ref{alg.is_permutation}, is permutation template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); // \ref{alg.search}, search template - ForwardIterator1 search( - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - ForwardIterator1 search( - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); template - ForwardIterator1 search( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + ForwardIterator1 + search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - ForwardIterator1 search( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + ForwardIterator1 + search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); template - ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value); + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); template - ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); template - ForwardIterator search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Size count, const T& value); + ForwardIterator + search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Size count, const T& value); template - ForwardIterator search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); + ForwardIterator + search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); - template - ForwardIterator search(ForwardIterator first, ForwardIterator last, - const Searcher& searcher); + template + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); - // \ref{alg.modifying.operations}, modifying sequence operations + // \ref{alg.modifying.operations}, mutating sequence operations // \ref{alg.copy}, copy template - OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); template ForwardIterator2 copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template - OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); template ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, Size n, ForwardIterator2 result); template - OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); template ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); template - BidirectionalIterator2 copy_backward( - BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + constexpr BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); // \ref{alg.move}, move template - OutputIterator move(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); template ForwardIterator2 move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template - BidirectionalIterator2 move_backward( - BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); // \ref{alg.swap}, swap template @@ -361,53 +362,57 @@ // \ref{alg.transform}, transform template - OutputIterator transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); + constexpr OutputIterator + transform(InputIterator first, InputIterator last, + OutputIterator result, UnaryOperation op); template - OutputIterator transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op); + constexpr OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op); template - ForwardIterator2 transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, UnaryOperation op); + ForwardIterator2 + transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, UnaryOperation op); template - ForwardIterator transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator result, - BinaryOperation binary_op); + ForwardIterator + transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator result, + BinaryOperation binary_op); // \ref{alg.replace}, replace template - void replace(ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); template void replace(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template - void replace_if(ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); template void replace_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); template - OutputIterator replace_copy(InputIterator first, InputIterator last, - OutputIterator result, - const T& old_value, const T& new_value); + constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, + OutputIterator result, + const T& old_value, const T& new_value); template ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, const T& new_value); template - OutputIterator replace_copy_if(InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); + constexpr OutputIterator replace_copy_if(InputIterator first, InputIterator last, + OutputIterator result, + Predicate pred, const T& new_value); template ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} @@ -417,70 +422,73 @@ // \ref{alg.fill}, fill template - void fill(ForwardIterator first, ForwardIterator last, const T& value); - template + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); + template void fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template - OutputIterator fill_n(OutputIterator first, Size n, const T& value); + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); template ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, const T& value); + ForwardIterator first, Size n, const T& value); // \ref{alg.generate}, generate template - void generate(ForwardIterator first, ForwardIterator last, - Generator gen); + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); template void generate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Generator gen); template - OutputIterator generate_n(OutputIterator first, Size n, Generator gen); + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); template ForwardIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, Generator gen); // \ref{alg.remove}, remove template - ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); template ForwardIterator remove(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template - ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred); + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); template ForwardIterator remove_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); template - OutputIterator remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value); + constexpr OutputIterator + remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value); template - ForwardIterator2 remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, const T& value); + ForwardIterator2 + remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); template - OutputIterator remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + constexpr OutputIterator + remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); template - ForwardIterator2 remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred); + ForwardIterator2 + remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); // \ref{alg.unique}, unique template - ForwardIterator unique(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); template - ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); template ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); @@ -489,20 +497,24 @@ ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template - OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result); template - OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result, BinaryPredicate pred); template - ForwardIterator2 unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); template - ForwardIterator2 unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, BinaryPredicate pred); + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); // \ref{alg.reverse}, reverse template @@ -511,14 +523,14 @@ void reverse(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} BidirectionalIterator first, BidirectionalIterator last); template - OutputIterator reverse_copy(BidirectionalIterator first, - BidirectionalIterator last, - OutputIterator result); + constexpr OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, + OutputIterator result); template - ForwardIterator reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, - BidirectionalIterator last, - ForwardIterator result); + ForwardIterator + reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator last, + ForwardIterator result); // \ref{alg.rotate}, rotate template @@ -531,14 +543,14 @@ ForwardIterator middle, ForwardIterator last); template - OutputIterator rotate_copy( - ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result); + constexpr OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, + ForwardIterator last, OutputIterator result); template - ForwardIterator2 rotate_copy( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 middle, - ForwardIterator1 last, ForwardIterator2 result); + ForwardIterator2 + rotate_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 middle, + ForwardIterator1 last, ForwardIterator2 result); // \ref{alg.random.sample}, sample template - bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); - template + template + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); + template bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); @@ -578,23 +590,23 @@ BidirectionalIterator first, BidirectionalIterator last, Predicate pred); - template - pair + template + constexpr pair partition_copy(InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); - template + template pair partition_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); template - ForwardIterator partition_point(ForwardIterator first, - ForwardIterator last, - Predicate pred); + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, + Predicate pred); // \ref{alg.sorting}, sorting and related operations // \ref{alg.sort}, sorting @@ -643,35 +655,35 @@ RandomAccessIterator middle, RandomAccessIterator last, Compare comp); template - RandomAccessIterator partial_sort_copy( - InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); + RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); template - RandomAccessIterator partial_sort_copy( - InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); + RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); template - RandomAccessIterator partial_sort_copy( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); template - RandomAccessIterator partial_sort_copy( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); template - bool is_sorted(ForwardIterator first, ForwardIterator last); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); template - bool is_sorted(ForwardIterator first, ForwardIterator last, - Compare comp); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); template bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); @@ -680,17 +692,21 @@ ForwardIterator first, ForwardIterator last, Compare comp); template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); template - ForwardIterator is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); template - ForwardIterator is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Compare comp); + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); // \ref{alg.nth.element}, Nth element template @@ -710,57 +726,67 @@ // \ref{alg.binary.search}, binary search template - ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value); template - ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); template - ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value); template - ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); template - pair + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value); template - pair + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); // \ref{alg.merge}, merge template - OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); + ForwardIterator + merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - ForwardIterator merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + ForwardIterator + merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template void inplace_merge(BidirectionalIterator first, @@ -783,11 +809,12 @@ // \ref{alg.set.operations}, set operations template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, Compare comp); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, @@ -796,103 +823,108 @@ class Compare> bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); template - OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); + ForwardIterator + set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - ForwardIterator set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + ForwardIterator + set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template - OutputIterator set_intersection( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator set_intersection( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator set_intersection( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); + ForwardIterator + set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - ForwardIterator set_intersection( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + ForwardIterator + set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template - OutputIterator set_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator set_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator set_difference( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); + ForwardIterator + set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - ForwardIterator set_difference( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + ForwardIterator + set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template - OutputIterator set_symmetric_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator set_symmetric_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator set_symmetric_difference( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - ForwardIterator set_symmetric_difference( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); // \ref{alg.heap.operations}, heap operations template @@ -920,27 +952,33 @@ Compare comp); template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); template bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last); template bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, Compare comp); + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); template - RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last); + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); template - RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); // \ref{alg.min.max}, minimum and maximum template constexpr const T& min(const T& a, const T& b); @@ -1014,26 +1052,40 @@ // \ref{alg.lex.comparison}, lexicographical comparison template - bool lexicographical_compare( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template - bool lexicographical_compare( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template - bool lexicographical_compare( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + bool + lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - bool lexicographical_compare( - ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Compare comp); + bool + lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + + // \ref{alg.3way}, three-way comparison algorithms + template + constexpr auto compare_3way(const T& a, const U& b); + template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> common_comparison_category_t; + template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); // \ref{alg.permutation.generators}, permutations template @@ -1112,7 +1164,7 @@ \pnum If an algorithm's \effects -section says that a value pointed to by any iterator passed +element specifies that a value pointed to by any iterator passed as an argument is modified, then that algorithm has an additional type requirement: The type of that argument shall satisfy the requirements @@ -1226,7 +1278,7 @@ \rSec1[algorithms.parallel]{Parallel algorithms} \pnum -This section describes components that \Cpp programs may use to perform +This subclause describes components that \Cpp{} programs may use to perform operations on containers and other sequences in parallel. \rSec2[algorithms.parallel.defns]{Terms and definitions} @@ -1362,9 +1414,9 @@ std::atomic x{0}; int a[] = {1,2}; std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { - x.fetch_add(1, std::memory_order_relaxed); + x.fetch_add(1, std::memory_order::relaxed); // spin wait for another iteration to change the value of \tcode{x} - while (x.load(std::memory_order_relaxed) == 1) { } // incorrect: assumes execution order + while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order }); \end{codeblock} The above example depends on the order of execution of the iterations, and @@ -1506,9 +1558,9 @@ \indexlibrary{\idxcode{all_of}}% \begin{itemdecl} -template - bool all_of(InputIterator first, InputIterator last, Predicate pred); -template +template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); +template bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1527,9 +1579,9 @@ \indexlibrary{\idxcode{any_of}}% \begin{itemdecl} -template - bool any_of(InputIterator first, InputIterator last, Predicate pred); -template +template + constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); +template bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1548,9 +1600,9 @@ \indexlibrary{\idxcode{none_of}}% \begin{itemdecl} -template - bool none_of(InputIterator first, InputIterator last, Predicate pred); -template +template + constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); +template bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1570,7 +1622,7 @@ \indexlibrary{\idxcode{for_each}}% \begin{itemdecl} template - Function for_each(InputIterator first, InputIterator last, Function f); + constexpr Function for_each(InputIterator first, InputIterator last, Function f); \end{itemdecl} \begin{itemdescr} @@ -1652,7 +1704,7 @@ \indexlibrary{\idxcode{for_each_n}}% \begin{itemdecl} template - InputIterator for_each_n(InputIterator first, Size n, Function f); + constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); \end{itemdecl} \begin{itemdescr} @@ -1728,22 +1780,22 @@ \indexlibrary{\idxcode{find_if_not}}% \begin{itemdecl} template - InputIterator find(InputIterator first, InputIterator last, - const T& value); + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); template ForwardIterator find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template - InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); template ForwardIterator find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); template - InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if_not(InputIterator first, InputIterator last, + Predicate pred); template ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); @@ -1773,7 +1825,7 @@ \indexlibrary{\idxcode{find_end}}% \begin{itemdecl} template - ForwardIterator1 + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template @@ -1784,7 +1836,7 @@ template - ForwardIterator1 + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -1828,7 +1880,7 @@ \indexlibrary{\idxcode{find_first_of}}% \begin{itemdecl} template - InputIterator + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); template @@ -1838,8 +1890,8 @@ ForwardIterator2 first2, ForwardIterator2 last2); template - InputIterator + class BinaryPredicate> + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); @@ -1884,18 +1936,22 @@ \indexlibrary{\idxcode{adjacent_find}}% \begin{itemdecl} template - ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); template - ForwardIterator adjacent_find(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); template - ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); template - ForwardIterator adjacent_find(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} @@ -1932,18 +1988,20 @@ \indexlibrary{\idxcode{count_if}}% \begin{itemdecl} template - typename iterator_traits::difference_type + constexpr typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); template typename iterator_traits::difference_type - count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); + count(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, const T& value); template - typename iterator_traits::difference_type + constexpr typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); template typename iterator_traits::difference_type - count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + count_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -1968,7 +2026,7 @@ \indexlibrary{\idxcode{mismatch}}% \begin{itemdecl} template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template @@ -1979,7 +2037,7 @@ template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template @@ -2001,7 +2059,7 @@ template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); @@ -2042,8 +2100,8 @@ \indexlibrary{\idxcode{equal}}% \begin{itemdecl} template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); template bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, @@ -2051,8 +2109,8 @@ template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); template bool equal(ExecutionPolicy&& exec, @@ -2060,8 +2118,8 @@ ForwardIterator2 first2, BinaryPredicate pred); template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, @@ -2069,9 +2127,9 @@ template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); template bool equal(ExecutionPolicy&& exec, @@ -2148,20 +2206,20 @@ \indexlibrary{\idxcode{is_permutation}}% \begin{itemdecl} template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); + class BinaryPredicate> + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + class BinaryPredicate> + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} @@ -2197,7 +2255,7 @@ \indexlibrary{\idxcode{search}}% \begin{itemdecl} template - ForwardIterator1 + constexpr ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template @@ -2208,7 +2266,7 @@ template - ForwardIterator1 + constexpr ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -2252,21 +2310,21 @@ \indexlibrary{\idxcode{search_n}}% \begin{itemdecl} template - ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, Size count, - const T& value); - -template - ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, Size count, - const T& value, BinaryPredicate pred); - + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); template ForwardIterator search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value); + +template + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); template ForwardIterator @@ -2311,8 +2369,8 @@ \indexlibrary{\idxcode{search}}% \begin{itemdecl} template - ForwardIterator search(ForwardIterator first, ForwardIterator last, - const Searcher& searcher); + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); \end{itemdecl} \begin{itemdescr} @@ -2333,8 +2391,8 @@ \indexlibrary{\idxcode{copy}}% \begin{itemdecl} template - OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); \end{itemdecl} \begin{itemdescr} @@ -2380,8 +2438,8 @@ \indexlibrary{\idxcode{copy_n}}% \begin{itemdecl} template - OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); template ForwardIterator2 copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, @@ -2403,9 +2461,10 @@ \indexlibrary{\idxcode{copy_if}}% \begin{itemdecl} template - OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); -template + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); +template ForwardIterator2 copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); @@ -2437,7 +2496,7 @@ \indexlibrary{\idxcode{copy_backward}}% \begin{itemdecl} template - BidirectionalIterator2 + constexpr BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); @@ -2483,7 +2542,8 @@ \indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} template - OutputIterator move(InputIterator first, InputIterator last, OutputIterator result); + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); \end{itemdecl} \begin{itemdescr} @@ -2543,9 +2603,8 @@ \indexlibrary{\idxcode{move_backward}}% \begin{itemdecl} template - BidirectionalIterator2 - move_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); \end{itemdecl} @@ -2650,7 +2709,7 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); template - OutputIterator + constexpr OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); @@ -2725,16 +2784,16 @@ \indexlibrary{\idxcode{replace_if}}% \begin{itemdecl} template - void replace(ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); template void replace(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template - void replace_if(ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); template void replace_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, @@ -2768,7 +2827,7 @@ \indexlibrary{\idxcode{replace_copy_if}}% \begin{itemdecl} template - OutputIterator + constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); @@ -2780,7 +2839,7 @@ const T& old_value, const T& new_value); template - OutputIterator + constexpr OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); @@ -2844,13 +2903,13 @@ \indexlibrary{\idxcode{fill_n}}% \begin{itemdecl} template - void fill(ForwardIterator first, ForwardIterator last, const T& value); + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); template void fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template - OutputIterator fill_n(OutputIterator first, Size n, const T& value); + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); template ForwardIterator fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value); @@ -2890,15 +2949,15 @@ \indexlibrary{\idxcode{generate_n}}% \begin{itemdecl} template - void generate(ForwardIterator first, ForwardIterator last, - Generator gen); + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); template void generate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Generator gen); template - OutputIterator generate_n(OutputIterator first, Size n, Generator gen); + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); template ForwardIterator generate_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Generator gen); @@ -2938,16 +2997,16 @@ \indexlibrary{\idxcode{remove_if}}% \begin{itemdecl} template - ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); template ForwardIterator remove(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template - ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred); + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); template ForwardIterator remove_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, @@ -2996,20 +3055,22 @@ \indexlibrary{\idxcode{remove_copy_if}}% \begin{itemdecl} template - OutputIterator + constexpr OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); -template +template ForwardIterator2 remove_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value); template - OutputIterator + constexpr OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); -template +template ForwardIterator2 remove_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, @@ -3058,14 +3119,14 @@ \indexlibrary{\idxcode{unique}}% \begin{itemdecl} template - ForwardIterator unique(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); template ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template - ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); template ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, @@ -3105,7 +3166,7 @@ \indexlibrary{\idxcode{unique_copy}}% \begin{itemdecl} template - OutputIterator + constexpr OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result); template @@ -3116,7 +3177,7 @@ template - OutputIterator + constexpr OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); template - OutputIterator + constexpr OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); template @@ -3319,7 +3380,7 @@ \indexlibrary{\idxcode{rotate_copy}}% \begin{itemdecl} template - OutputIterator + constexpr OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); template @@ -3797,7 +3858,7 @@ \indexlibrary{\idxcode{is_sorted}}% \begin{itemdecl} template - bool is_sorted(ForwardIterator first, ForwardIterator last); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); \end{itemdecl} \begin{itemdescr} @@ -3821,8 +3882,8 @@ \indexlibrary{\idxcode{is_sorted}}% \begin{itemdecl} template - bool is_sorted(ForwardIterator first, ForwardIterator last, - Compare comp); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} @@ -3851,18 +3912,22 @@ \indexlibrary{\idxcode{is_sorted_until}}% \begin{itemdecl} template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); template - ForwardIterator is_sorted_until(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); template - ForwardIterator is_sorted_until(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Compare comp); + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); \end{itemdecl} @@ -3937,7 +4002,7 @@ \rSec2[alg.binary.search]{Binary search} \pnum -All of the algorithms in this section are versions of binary search +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. @@ -3953,12 +4018,12 @@ \indexlibrary{\idxcode{lower_bound}}% \begin{itemdecl} template - ForwardIterator + constexpr ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value); template - ForwardIterator + constexpr ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); \end{itemdecl} @@ -4002,12 +4067,12 @@ \indexlibrary{\idxcode{upper_bound}}% \begin{itemdecl} template - ForwardIterator + constexpr ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value); template - ForwardIterator + constexpr ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); \end{itemdecl} @@ -4051,12 +4116,12 @@ \indexlibrary{\idxcode{equal_range}}% \begin{itemdecl} template - pair + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value); template - pair + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); @@ -4113,12 +4178,14 @@ \indexlibrary{\idxcode{binary_search}}% \begin{itemdecl} template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value); + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4128,7 +4195,7 @@ \tcode{e} of \range{first}{last} -are partitioned with respect to the expressions +shall be partitioned with respect to the expressions \tcode{e < value} and \tcode{!(value < e)} @@ -4141,11 +4208,11 @@ of \tcode{[first, last)}, \tcode{e < value} -implies +shall imply \tcode{!(value < e)} or \tcode{comp(e, value)} -implies +shall imply \tcode{!comp(value, e)}. \pnum @@ -4171,9 +4238,9 @@ \indexlibrary{\idxcode{is_partitioned}}% \begin{itemdecl} -template - bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); -template +template + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); +template bool is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -4189,7 +4256,9 @@ \pnum \returns \tcode{true} if \range{first}{last} is empty or if -\range{first}{last} is partitioned by \tcode{pred}, i.e. if all elements that satisfy \tcode{pred} appear before those that do not. +the elements \tcode{e} of +\range{first}{last} are partitioned with respect to the expression +\tcode{pred(e)}. \pnum \complexity Linear. At most \tcode{last - first} applications of \tcode{pred}. @@ -4236,13 +4305,11 @@ \begin{itemdecl} template BidirectionalIterator - stable_partition(BidirectionalIterator first, BidirectionalIterator last, - Predicate pred); + stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred); template BidirectionalIterator stable_partition(ExecutionPolicy&& exec, - BidirectionalIterator first, BidirectionalIterator last, - Predicate pred); + BidirectionalIterator first, BidirectionalIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -4292,22 +4359,19 @@ \indexlibrary{\idxcode{partition_copy}}% \begin{itemdecl} -template - pair +template + constexpr pair partition_copy(InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, - Predicate pred); -template + OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); +template pair partition_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - ForwardIterator1 out_true, ForwardIterator2 out_false, - Predicate pred); + ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); \end{itemdecl} - \begin{itemdescr} \pnum \requires @@ -4346,15 +4410,16 @@ \indexlibrary{\idxcode{partition_point}}% \begin{itemdecl} template - ForwardIterator partition_point(ForwardIterator first, - ForwardIterator last, - Predicate pred); + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} - \begin{itemdescr} \pnum -\requires \tcode{ForwardIterator}'s value type shall be convertible to \tcode{Predicate}'s argument type. \range{first}{last} shall be partitioned by \tcode{pred}, i.e. all elements that satisfy \tcode{pred} shall appear before those that do not. +\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)}. \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}. @@ -4369,7 +4434,7 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); @@ -4383,7 +4448,7 @@ template - OutputIterator + constexpr OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -4403,10 +4468,10 @@ 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 +\effects Copies all the elements of the two ranges \range{first1}{last1} and \range{first2}{last2} into the range \range{result}{result_last}, where \tcode{result_last} is \tcode{result + (last1 - first1) + (last2 - first2)}, such that the resulting range satisfies -\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(result, result_last, comp)}, respectively. +\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(re\-sult, result_last, comp)}, respectively. \pnum \returns @@ -4496,7 +4561,7 @@ \rSec2[alg.set.operations]{Set operations on sorted structures} \pnum -This section defines all the basic set operations on sorted structures. +This subclause defines all the basic set operations on sorted structures. They also work with \tcode{multiset}s\iref{multiset} containing multiple copies of equivalent elements. @@ -4513,17 +4578,17 @@ \indexlibrary{\idxcode{includes}}% \begin{itemdecl} template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template bool includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template bool includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, @@ -4557,7 +4622,7 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); @@ -4571,7 +4636,7 @@ template - OutputIterator + constexpr OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -4618,7 +4683,7 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); @@ -4632,7 +4697,7 @@ template - OutputIterator + constexpr OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -4678,12 +4743,12 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template + class ForwardIterator> ForwardIterator set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, @@ -4692,7 +4757,7 @@ template - OutputIterator + constexpr OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -4751,7 +4816,7 @@ \begin{itemdecl} template - OutputIterator + constexpr OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); @@ -4765,7 +4830,7 @@ template - OutputIterator + constexpr OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -4996,7 +5061,7 @@ \indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); \end{itemdecl} \begin{itemdescr} @@ -5021,7 +5086,8 @@ \indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} @@ -5034,7 +5100,8 @@ \begin{itemdecl} template bool is_heap(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, Compare comp); + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} @@ -5049,18 +5116,22 @@ \indexlibrary{\idxcode{is_heap_until}}% \begin{itemdecl} template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); template - RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last); + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); template - RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} @@ -5397,7 +5468,7 @@ \indexlibrary{\idxcode{lexicographical_compare}}% \begin{itemdecl} template - bool + constexpr bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template @@ -5407,11 +5478,12 @@ ForwardIterator2 first2, ForwardIterator2 last2); template - bool + constexpr bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); -template +template bool lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, @@ -5466,6 +5538,92 @@ \end{itemdescr} +\rSec2[alg.3way]{Three-way comparison algorithms} + +\indexlibrary{\idxcode{compare_3way}}% +\begin{itemdecl} +template constexpr auto compare_3way(const T& a, const U& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of the strongest applicable +comparison category type: +\begin{itemize} +\item +Returns \tcode{a <=> b} if that expression is well-formed. +\item +Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} +are each well-formed and convertible to \tcode{bool}, +returns \tcode{strong_ordering::equal} +when \tcode{a == b} is \tcode{true}, +otherwise returns \tcode{strong_ordering::less} +when \tcode{a < b} is \tcode{true}, +and otherwise returns \tcode{strong_ordering::greater}. +\item +Otherwise, if the expression \tcode{a == b} +is well-formed and convertible to \tcode{bool}, +returns \tcode{strong_equality::equal} +when \tcode{a == b} is \tcode{true}, +and otherwise returns \tcode{strong_equality::nonequal}. +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{lexicographical_compare_3way}}% +\begin{itemdecl} +template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> common_comparison_category_t; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\tcode{Cmp} shall be a function object type +whose return type is a comparison category type. + +\pnum +\effects +Lexicographically compares two ranges and +produces a result of the strongest applicable +comparison category type. +Equivalent to: +\begin{codeblock} +for ( ; b1 != e1 && b2 != e2; void(++b1), void(++b2) ) + if (auto cmp = comp(*b1,*b2); cmp != 0) + return cmp; +return b1 != e1 ? strong_ordering::greater : + b2 != e2 ? strong_ordering::less : + strong_ordering::equal; +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{lexicographical_compare_3way}}% +\begin{itemdecl} +template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return lexicographical_compare_3way(b1, e1, b2, e2, + [](const auto& t, const auto& u) { + return compare_3way(t, u); + }); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.permutation.generators]{Permutation generators} \indexlibrary{\idxcode{next_permutation}}% @@ -5555,8 +5713,7 @@ \rSec1[alg.c.library]{C library algorithms} \pnum -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% \begin{note} The header \tcode{}\iref{cstdlib.syn} declares the functions described in this subclause. diff --git a/source/atomics.tex b/source/atomics.tex index b02ad72121..849e7ff63f 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -28,13 +28,12 @@ \rSec1[atomics.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{atomic}}% -\indexlibrary{\idxhdr{atomic}}% +\indexhdr{atomic}% \begin{codeblock} namespace std { // \ref{atomics.order}, order and consistency - enum memory_order; - template + enum class memory_order : @\unspec@; + template T kill_dependency(T y) noexcept; // \ref{atomics.lockfree}, lock-free property @@ -82,7 +81,7 @@ template T atomic_load_explicit(const atomic*, memory_order) noexcept; template - T atomic_exchange(volatile atomic*, T) noexcept; + T atomic_exchange(volatile atomic*, typename atomic::value_type) noexcept; template T atomic_exchange(atomic*, typename atomic::value_type) noexcept; template @@ -128,54 +127,54 @@ typename atomic::value_type, memory_order, memory_order) noexcept; - template + template T atomic_fetch_add(volatile atomic*, typename atomic::difference_type) noexcept; - template + template T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; - template + template T atomic_fetch_add_explicit(volatile atomic*, typename atomic::difference_type, memory_order) noexcept; - template + template T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, memory_order) noexcept; - template + template T atomic_fetch_sub(volatile atomic*, typename atomic::difference_type) noexcept; - template + template T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; - template + template T atomic_fetch_sub_explicit(volatile atomic*, typename atomic::difference_type, memory_order) noexcept; - template + template T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, memory_order) noexcept; - template + template T atomic_fetch_and(volatile atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_and_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; - template + template T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; - template + template T atomic_fetch_or(volatile atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_or_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; - template + template T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; - template + template T atomic_fetch_xor(volatile atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; - template + template T atomic_fetch_xor_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; - template + template T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; @@ -306,13 +305,31 @@ are defined, respectively. \rSec1[atomics.order]{Order and consistency} +\indexlibrary{memory_order}% +\indexlibrarymember{relaxed}{memory_order}% +\indexlibrarymember{consume}{memory_order}% +\indexlibrarymember{acquire}{memory_order}% +\indexlibrarymember{release}{memory_order}% +\indexlibrarymember{acq_rel}{memory_order}% +\indexlibrarymember{seq_cst}{memory_order}% +\indexlibrary{memory_order_relaxed}% +\indexlibrary{memory_order_consume}% +\indexlibrary{memory_order_acquire}% +\indexlibrary{memory_order_release}% +\indexlibrary{memory_order_acq_rel}% +\indexlibrary{memory_order_seq_cst}% \begin{codeblock} namespace std { - enum memory_order { - memory_order_relaxed, memory_order_consume, memory_order_acquire, - memory_order_release, memory_order_acq_rel, memory_order_seq_cst + enum class memory_order : @\unspec@ { + relaxed, consume, acquire, release, acq_rel, seq_cst }; + inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; + inline constexpr memory_order memory_order_consume = memory_order::consume; + inline constexpr memory_order memory_order_acquire = memory_order::acquire; + inline constexpr memory_order memory_order_release = memory_order::release; + inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; + inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; } \end{codeblock} @@ -323,25 +340,25 @@ enumerated values and their meanings are as follows: \begin{itemize} -\item \tcode{memory_order_relaxed}: no operation orders memory. +\item \tcode{memory_order::relaxed}: no operation orders memory. -\item \tcode{memory_order_release}, \tcode{memory_order_acq_rel}, and -\tcode{memory_order_seq_cst}: a store operation performs a release operation on the +\item \tcode{memory_order::release}, \tcode{memory_order::acq_rel}, and +\tcode{memory_order::seq_cst}: a store operation performs a release operation on the affected memory location. -\item \tcode{memory_order_consume}: a load operation performs a consume operation on the +\item \tcode{memory_order::consume}: a load operation performs a consume operation on the affected memory location. -\begin{note} Prefer \tcode{memory_order_acquire}, which provides stronger guarantees -than \tcode{memory_order_consume}. Implementations have found it infeasible -to provide performance better than that of \tcode{memory_order_acquire}. +\begin{note} Prefer \tcode{memory_order::acquire}, which provides stronger guarantees +than \tcode{memory_order::consume}. Implementations have found it infeasible +to provide performance better than that of \tcode{memory_order::acquire}. Specification revisions are under consideration. \end{note} -\item \tcode{memory_order_acquire}, \tcode{memory_order_acq_rel}, and -\tcode{memory_order_seq_cst}: a load operation performs an acquire operation on the +\item \tcode{memory_order::acquire}, \tcode{memory_order::acq_rel}, and +\tcode{memory_order::seq_cst}: a load operation performs an acquire operation on the affected memory location. \end{itemize} -\begin{note} Atomic operations specifying \tcode{memory_order_relaxed} are relaxed +\begin{note} Atomic operations specifying \tcode{memory_order::relaxed} are relaxed with respect to memory ordering. Implementations must still guarantee that any given atomic access to a particular atomic object be indivisible with respect to all other atomic accesses to that object. \end{note} @@ -353,9 +370,9 @@ release sequence headed by \placeholder{A}. \pnum -There shall be a single total order \placeholder{S} on all \tcode{memory_order_seq_cst} +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 +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: @@ -366,11 +383,11 @@ \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 +\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}. +\tcode{memory_order::seq_cst}. \end{itemize} \begin{note} Although it is not explicitly required that \placeholder{S} include locks, it can @@ -379,15 +396,15 @@ \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 +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 +\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. @@ -395,7 +412,7 @@ \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 +\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. @@ -405,21 +422,21 @@ \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} +\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} +\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} +\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} \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} +\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 +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} @@ -431,14 +448,14 @@ \begin{codeblock} // Thread 1: -r1 = y.load(memory_order_relaxed); -x.store(r1, memory_order_relaxed); +r1 = y.load(memory_order::relaxed); +x.store(r1, memory_order::relaxed); \end{codeblock} \begin{codeblock} // Thread 2: -r2 = x.load(memory_order_relaxed); -y.store(r2, memory_order_relaxed); +r2 = x.load(memory_order::relaxed); +y.store(r2, memory_order::relaxed); \end{codeblock} should not produce \tcode{r1 == r2 == 42}, since the store of 42 to \tcode{y} is only @@ -453,14 +470,14 @@ \begin{codeblock} // Thread 1: -r1 = x.load(memory_order_relaxed); -if (r1 == 42) y.store(42, memory_order_relaxed); +r1 = x.load(memory_order::relaxed); +if (r1 == 42) y.store(42, memory_order::relaxed); \end{codeblock} \begin{codeblock} // Thread 2: -r2 = y.load(memory_order_relaxed); -if (r2 == 42) x.store(42, memory_order_relaxed); +r2 = y.load(memory_order::relaxed); +if (r2 == 42) x.store(42, memory_order::relaxed); \end{codeblock} \end{note} @@ -476,7 +493,7 @@ \indexlibrary{\idxcode{kill_dependency}}% \begin{itemdecl} -template +template T kill_dependency(T y) noexcept; \end{itemdecl} @@ -545,29 +562,30 @@ \rSec1[atomics.types.generic]{Class template \tcode{atomic}} \indexlibrary{\idxcode{atomic}}% +\indexlibrarymember{value_type}{atomic}% \begin{codeblock} namespace std { - template struct atomic { + template struct atomic { using value_type = T; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(T, memory_order = memory_order_seq_cst) volatile noexcept; - void store(T, memory_order = memory_order_seq_cst) noexcept; - T load(memory_order = memory_order_seq_cst) const volatile noexcept; - T load(memory_order = memory_order_seq_cst) const noexcept; + void store(T, memory_order = memory_order::seq_cst) volatile noexcept; + void store(T, memory_order = memory_order::seq_cst) noexcept; + T load(memory_order = memory_order::seq_cst) const volatile noexcept; + T load(memory_order = memory_order::seq_cst) const noexcept; operator T() const volatile noexcept; operator T() const noexcept; - T exchange(T, memory_order = memory_order_seq_cst) volatile noexcept; - T exchange(T, memory_order = memory_order_seq_cst) noexcept; + T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept; + T exchange(T, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept; bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept; bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept; - bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept; + bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept; + bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept; + bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept; atomic() noexcept = default; constexpr atomic(T) noexcept; @@ -605,6 +623,7 @@ \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}% +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}!constructor}% \begin{itemdecl} atomic() noexcept = default; \end{itemdecl} @@ -621,6 +640,7 @@ \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}% +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}!constructor}% \begin{itemdecl} constexpr atomic(T desired) noexcept; \end{itemdecl} @@ -632,7 +652,7 @@ \begin{note} It is possible to have an access to an atomic object \tcode{A} race with its construction, for example by communicating the address of the just-constructed object \tcode{A} to another thread via -\tcode{memory_order_relaxed} operations on a suitable atomic pointer +\tcode{memory_order::relaxed} operations on a suitable atomic pointer variable, and then immediately accessing \tcode{A} in the receiving thread. This results in undefined behavior. \end{note} \end{itemdescr} @@ -660,6 +680,7 @@ \indexlibrarymember{is_always_lock_free}{atomic}% \indexlibrarymember{is_always_lock_free}{atomic}% \indexlibrarymember{is_always_lock_free}{atomic<\placeholder{integral}>}% +\indexlibrarymember{is_always_lock_free}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; \end{itemdecl} @@ -678,6 +699,7 @@ \indexlibrarymember{is_lock_free}{atomic}% \indexlibrarymember{is_lock_free}{atomic}% \indexlibrarymember{is_lock_free}{atomic<\placeholder{integral}>}% +\indexlibrarymember{is_lock_free}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; @@ -697,15 +719,16 @@ \indexlibrarymember{store}{atomic}% \indexlibrarymember{store}{atomic}% \indexlibrarymember{store}{atomic<\placeholder{integral}>}% +\indexlibrarymember{store}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} -void store(T desired, memory_order order = memory_order_seq_cst) volatile noexcept; -void store(T desired, memory_order order = memory_order_seq_cst) noexcept; +void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; +void store(T desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_consume}, -\tcode{memory_order_acquire}, nor \tcode{memory_order_acq_rel}. +\requires The \tcode{order} argument shall not be \tcode{memory_order::consume}, +\tcode{memory_order::acquire}, nor \tcode{memory_order::acq_rel}. \pnum \effects Atomically replaces the value pointed to by \tcode{this} @@ -716,6 +739,7 @@ \indexlibrarymember{operator=}{atomic}% \indexlibrarymember{operator=}{atomic}% \indexlibrarymember{operator=}{atomic<\placeholder{integral}>}% +\indexlibrarymember{operator=}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} T operator=(T desired) volatile noexcept; T operator=(T desired) noexcept; @@ -723,7 +747,7 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{store(desired)}. +\effects Equivalent to \tcode{store(desired)}. \pnum \returns \tcode{desired}. @@ -734,14 +758,15 @@ \indexlibrarymember{load}{atomic}% \indexlibrarymember{load}{atomic}% \indexlibrarymember{load}{atomic<\placeholder{integral}>}% +\indexlibrarymember{load}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} -T load(memory_order order = memory_order_seq_cst) const volatile noexcept; -T load(memory_order order = memory_order_seq_cst) const noexcept; +T load(memory_order order = memory_order::seq_cst) const volatile noexcept; +T load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_release} nor \tcode{memory_order_acq_rel}. +\requires The \tcode{order} argument shall not be \tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. \pnum \effects Memory is affected according to the value of \tcode{order}. @@ -753,6 +778,7 @@ \indexlibrarymember{operator \placeholder{type}}{atomic}% \indexlibrarymember{operator T*}{atomic}% \indexlibrarymember{operator \placeholder{integral}}{atomic<\placeholder{integral}>}% +\indexlibrarymember{operator \placeholder{floating-point}}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} operator T() const volatile noexcept; operator T() const noexcept; @@ -769,9 +795,10 @@ \indexlibrarymember{exchange}{atomic}% \indexlibrarymember{exchange}{atomic}% \indexlibrarymember{exchange}{atomic<\placeholder{integral}>}% +\indexlibrarymember{exchange}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} -T exchange(T desired, memory_order order = memory_order_seq_cst) volatile noexcept; -T exchange(T desired, memory_order order = memory_order_seq_cst) noexcept; +T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; +T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -792,9 +819,11 @@ \indexlibrarymember{compare_exchange_weak}{atomic}% \indexlibrarymember{compare_exchange_weak}{atomic}% \indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{integral}>}% +\indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{floating-point}>}% \indexlibrarymember{compare_exchange_strong}{atomic}% \indexlibrarymember{compare_exchange_strong}{atomic}% \indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{integral}>}% +\indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{floating-point}>}% \begin{itemdecl} bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; @@ -805,19 +834,19 @@ bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) noexcept; bool compare_exchange_weak(T& expected, T desired, - memory_order order = memory_order_seq_cst) volatile noexcept; + memory_order order = memory_order::seq_cst) volatile noexcept; bool compare_exchange_weak(T& expected, T desired, - memory_order order = memory_order_seq_cst) noexcept; + memory_order order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T& expected, T desired, - memory_order order = memory_order_seq_cst) volatile noexcept; + memory_order order = memory_order::seq_cst) volatile noexcept; bool compare_exchange_strong(T& expected, T desired, - memory_order order = memory_order_seq_cst) noexcept; + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires The \tcode{failure} argument shall not be \tcode{memory_order_release} nor -\tcode{memory_order_acq_rel}. +\requires The \tcode{failure} argument shall not be \tcode{memory_order::release} nor +\tcode{memory_order::acq_rel}. \pnum \effects Retrieves the value in \tcode{expected}. It then atomically @@ -829,10 +858,10 @@ value of \tcode{success}, and if the comparison is false, memory is affected according to the value of \tcode{failure}. When only one \tcode{memory_order} argument is supplied, the value of \tcode{success} is \tcode{order}, and the value of -\tcode{failure} is \tcode{order} except that a value of \tcode{memory_order_acq_rel} -shall be replaced by the value \tcode{memory_order_acquire} and a value of -\tcode{memory_order_release} shall be replaced by the value -\tcode{memory_order_relaxed}. +\tcode{failure} is \tcode{order} except that a value of \tcode{memory_order::acq_rel} +shall be replaced by the value \tcode{memory_order::acquire} and a value of +\tcode{memory_order::release} shall be replaced by the value +\tcode{memory_order::relaxed}. If and only if the comparison is false then, after the atomic operation, the contents of the memory in \tcode{expected} are replaced by the value read from the memory pointed to by \tcode{this} during the atomic comparison. @@ -893,7 +922,6 @@ machines, e.g., load-locked store-conditional machines. A consequence of spurious failure is that nearly all uses of weak compare-and-exchange will be in a loop. - When a compare-and-exchange is in a loop, the weak version will yield better performance on some platforms. When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is preferable. @@ -935,20 +963,20 @@ \begin{codeblock} namespace std { - template <> struct atomic<@\placeholder{integral}@> { + template<> struct atomic<@\placeholder{integral}@> { using value_type = @\placeholder{integral}@; using difference_type = value_type; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - void store(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ load(memory_order = memory_order_seq_cst) const volatile noexcept; - @\placeholdernc{integral}@ load(memory_order = memory_order_seq_cst) const noexcept; + void store(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + void store(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ load(memory_order = memory_order::seq_cst) const volatile noexcept; + @\placeholdernc{integral}@ load(memory_order = memory_order::seq_cst) const noexcept; operator @\placeholdernc{integral}@() const volatile noexcept; operator @\placeholdernc{integral}@() const noexcept; - @\placeholdernc{integral}@ exchange(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ exchange(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; + @\placeholdernc{integral}@ exchange(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ exchange(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, @@ -958,23 +986,23 @@ bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholdernc{integral}@, memory_order, memory_order) noexcept; bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) volatile noexcept; + memory_order = memory_order::seq_cst) volatile noexcept; bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) volatile noexcept; + memory_order = memory_order::seq_cst) volatile noexcept; bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ fetch_add(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ fetch_add(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ fetch_sub(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ fetch_sub(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ fetch_and(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ fetch_and(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ fetch_or(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ fetch_or(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\placeholdernc{integral}@ fetch_xor(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\placeholdernc{integral}@ fetch_xor(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ fetch_add(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ fetch_add(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ fetch_sub(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ fetch_sub(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ fetch_and(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ fetch_and(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ fetch_or(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ fetch_or(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{integral}@ fetch_xor(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) volatile noexcept; + @\placeholdernc{integral}@ fetch_xor(@\placeholdernc{integral}@, memory_order = memory_order::seq_cst) noexcept; atomic() noexcept = default; constexpr atomic(@\placeholdernc{integral}@) noexcept; @@ -1060,8 +1088,8 @@ \indexlibrarymember{fetch_sub}{atomic<\placeholder{integral}>}% \indexlibrarymember{fetch_xor}{atomic<\placeholder{integral}>}% \begin{itemdecl} -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) volatile noexcept; -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) noexcept; +T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; +T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1098,37 +1126,188 @@ \effects Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;} \end{itemdescr} +\rSec2[atomics.types.float]{Specializations for floating-point types} + +\indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}}% +\pnum +There are specializations of the \tcode{atomic} +template for the floating-point types +\tcode{float}, +\tcode{double}, and +\tcode{long double}. +For each such floating-point type \tcode{\placeholdernc{floating-point}}, +the specialization \tcode{atomic<\placeholder{floating-point}>} +provides additional atomic operations appropriate to floating-point types. + +\begin{codeblock} +namespace std { + template<> struct atomic<@\placeholder{floating-point}@> { + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; + bool is_lock_free() const volatile noexcept; + bool is_lock_free() const noexcept; + void store(@\placeholdernc{floating-point}@, memory_order = memory_order_seq_cst) volatile noexcept; + void store(@\placeholdernc{floating-point}@, memory_order = memory_order_seq_cst) noexcept; + @\placeholdernc{floating-point}@ load(memory_order = memory_order_seq_cst) volatile noexcept; + @\placeholdernc{floating-point}@ load(memory_order = memory_order_seq_cst) noexcept; + operator @\placeholdernc{floating-point}@() volatile noexcept; + operator @\placeholdernc{floating-point}@() noexcept; + @\placeholdernc{floating-point}@ exchange(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) volatile noexcept; + @\placeholdernc{floating-point}@ exchange(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order, memory_order) volatile noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order, memory_order) noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order, memory_order) volatile noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order, memory_order) noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) noexcept; + + @\placeholdernc{floating-point}@ fetch_add(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) volatile noexcept; + @\placeholdernc{floating-point}@ fetch_add(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) noexcept; + @\placeholdernc{floating-point}@ fetch_sub(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) volatile noexcept; + @\placeholdernc{floating-point}@ fetch_sub(@\placeholdernc{floating-point}@, + memory_order = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(@\placeholder{floating-point}@) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + @\placeholdernc{floating-point}@ operator=(@\placeholder{floating-point}@) volatile noexcept; + @\placeholdernc{floating-point}@ operator=(@\placeholder{floating-point}@) noexcept; + + @\placeholdernc{floating-point}@ operator+=(@\placeholder{floating-point}@) volatile noexcept; + @\placeholdernc{floating-point}@ operator+=(@\placeholder{floating-point}@) noexcept; + @\placeholdernc{floating-point}@ operator-=(@\placeholder{floating-point}@) volatile noexcept; + @\placeholdernc{floating-point}@ operator-=(@\placeholder{floating-point}@) noexcept; + }; +} +\end{codeblock} + +\pnum +The atomic floating-point specializations +are standard-layout structs. +They each have a trivial default constructor +and a trivial destructor. + +\pnum +Descriptions are provided below only for members that differ from the primary template. + +\pnum +The following operations perform arithmetic addition and subtraction computations. +The key, operator, and computation correspondence are identified in +Table~\ref{tab:atomic.arithmetic.computations}. + +\indexlibrary{\idxcode{atomic_fetch_add}}% +\indexlibrary{\idxcode{atomic_fetch_sub}}% +\indexlibrary{\idxcode{atomic_fetch_add_explicit}}% +\indexlibrary{\idxcode{atomic_fetch_sub_explicit}}% +\indexlibrarymember{fetch_add}{atomic<\placeholder{floating-point}>}% +\indexlibrarymember{fetch_sub}{atomic<\placeholder{floating-point}>}% +\begin{itemdecl} +T A::fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) volatile noexcept; +T A::fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order_seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Atomically replaces the value pointed to by \tcode{this} +with the result of the computation applied to the value pointed +to by \tcode{this} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic read-modify-write operations\iref{intro.multithread}. + +\pnum +\returns +Atomically, the value pointed to by \tcode{this} immediately before the effects. + +\pnum +\remarks +If the result is not a representable value for its type\iref{expr.pre} +the result is unspecified, but the operations otherwise have no undefined +behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point}} +should conform to the \tcode{std::numeric_limits<\placeholder{floating-point}>} +traits associated with the floating-point type\iref{limits.syn}. +The floating-point environment\iref{cfenv} for atomic arithmetic operations +on \tcode{\placeholder{floating-point}} may be different than the +calling thread's floating-point environment. +\end{itemdescr} + +\indexlibrarymember{operator+=}{atomic}% +\indexlibrarymember{operator-=}{atomic}% +\indexlibrarymember{operator+=}{atomic<\placeholder{floating-point}>}% +\indexlibrarymember{operator-=}{atomic<\placeholder{floating-point}>}% +\begin{itemdecl} +T operator @\placeholder{op}@=(T operand) volatile noexcept; +T operator @\placeholder{op}@=(T operand) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;} + +\pnum +\remarks +If the result is not a representable value for its type\iref{expr.pre} +the result is unspecified, but the operations otherwise have no undefined +behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point}} +should conform to the \tcode{std::numeric_limits<\placeholder{floating-point}>} +traits associated with the floating-point type\iref{limits.syn}. +The floating-point environment\iref{cfenv} for atomic arithmetic operations +on \tcode{\placeholder{floating-point}} may be different than the +calling thread's floating-point environment. +\end{itemdescr} + \rSec2[atomics.types.pointer]{Partial specialization for pointers} \indexlibrary{\idxcode{atomic}}% \begin{codeblock} namespace std { - template struct atomic { + template struct atomic { using value_type = T*; using difference_type = ptrdiff_t; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(T*, memory_order = memory_order_seq_cst) volatile noexcept; - void store(T*, memory_order = memory_order_seq_cst) noexcept; - T* load(memory_order = memory_order_seq_cst) const volatile noexcept; - T* load(memory_order = memory_order_seq_cst) const noexcept; + void store(T*, memory_order = memory_order::seq_cst) volatile noexcept; + void store(T*, memory_order = memory_order::seq_cst) noexcept; + T* load(memory_order = memory_order::seq_cst) const volatile noexcept; + T* load(memory_order = memory_order::seq_cst) const noexcept; operator T*() const volatile noexcept; operator T*() const noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) noexcept; + T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept; + T* exchange(T*, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(T*&, T*, + memory_order = memory_order::seq_cst) volatile noexcept; + bool compare_exchange_weak(T*&, T*, + memory_order = memory_order::seq_cst) noexcept; + bool compare_exchange_strong(T*&, T*, + memory_order = memory_order::seq_cst) volatile noexcept; + bool compare_exchange_strong(T*&, T*, + memory_order = memory_order::seq_cst) noexcept; + T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; + T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; + T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; + T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; atomic() noexcept = default; constexpr atomic(T*) noexcept; @@ -1191,8 +1370,8 @@ \indexlibrarymember{fetch_add}{atomic}% \indexlibrarymember{fetch_sub}{atomic}% \begin{itemdecl} -T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order_seq_cst) volatile noexcept; -T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order_seq_cst) noexcept; +T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept; +T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1321,10 +1500,10 @@ \begin{codeblock} namespace std { struct atomic_flag { - bool test_and_set(memory_order = memory_order_seq_cst) volatile noexcept; - bool test_and_set(memory_order = memory_order_seq_cst) noexcept; - void clear(memory_order = memory_order_seq_cst) volatile noexcept; - void clear(memory_order = memory_order_seq_cst) noexcept; + bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept; + bool test_and_set(memory_order = memory_order::seq_cst) noexcept; + void clear(memory_order = memory_order::seq_cst) volatile noexcept; + void clear(memory_order = memory_order::seq_cst) noexcept; atomic_flag() noexcept = default; atomic_flag(const atomic_flag&) = delete; @@ -1375,8 +1554,8 @@ bool atomic_flag_test_and_set(atomic_flag* object) noexcept; bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept; bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept; -bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) volatile noexcept; -bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) noexcept; +bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept; +bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1396,14 +1575,14 @@ void atomic_flag_clear(atomic_flag* object) noexcept; void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept; void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept; -void atomic_flag::clear(memory_order order = memory_order_seq_cst) volatile noexcept; -void atomic_flag::clear(memory_order order = memory_order_seq_cst) noexcept; +void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept; +void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_consume}, -\tcode{memory_order_acquire}, nor \tcode{memory_order_acq_rel}. +\requires The \tcode{order} argument shall not be \tcode{memory_order::consume}, +\tcode{memory_order::acquire}, nor \tcode{memory_order::acq_rel}. \pnum \effects Atomically sets the value pointed to by \tcode{object} or by \tcode{this} to @@ -1413,7 +1592,7 @@ \rSec1[atomics.fences]{Fences} \pnum -This section introduces synchronization primitives called \term{fences}. Fences can have +This subclause introduces synchronization primitives called \term{fences}. Fences can have acquire semantics, release semantics, or both. A fence with acquire semantics is called an \term{acquire fence}. A fence with release semantics is called a \term{release fence}. @@ -1451,17 +1630,15 @@ \effects Depending on the value of \tcode{order}, this operation: \begin{itemize} -\item has no effects, if \tcode{order == memory_order_relaxed}; +\item has no effects, if \tcode{order == memory_order::relaxed}; -\item is an acquire fence, if \tcode{order == memory_order_acquire || order == -memory_order_consume}; +\item is an acquire fence, if \tcode{order == memory_order::acquire} or \tcode{order == memory_order::consume}; -\item is a release fence, if \tcode{order == memory_order_release}; +\item is a release fence, if \tcode{order == memory_order::release}; -\item is both an acquire fence and a release fence, if \tcode{order == -memory_order_acq_rel}; +\item is both an acquire fence and a release fence, if \tcode{order == memory_order::acq_rel}; -\item is a sequentially consistent acquire and release fence, if \tcode{order == memory_order_seq_cst}. +\item is a sequentially consistent acquire and release fence, if \tcode{order == memory_order::seq_cst}. \end{itemize} \end{itemdescr} diff --git a/source/back.tex b/source/back.tex index ec39597f7b..8d57a19ecb 100644 --- a/source/back.tex +++ b/source/back.tex @@ -9,7 +9,10 @@ \chapter{Bibliography} \item ISO/IEC 10967-1:2012, \doccite{Information technology --- Language independent arithmetic --- - Part 1: Integer and floating point arithmetic} + Part 1: Integer and floating point arithmetic} +\item + ISO 4217:2015, + \doccite{Codes for the representation of currencies} \end{itemize} The arithmetic specification described in ISO/IEC 10967-1:2012 is @@ -22,8 +25,8 @@ \chapter{Bibliography} \clearpage \renewcommand{\glossaryname}{Cross references} -\renewcommand{\preglossaryhook}{This annex lists each section label and the -corresponding section number and page number, in alphabetical order by label.\\} +\renewcommand{\preglossaryhook}{This annex lists each clause or subclause label and the +corresponding clause or subclause number and page number, in alphabetical order by label.\\} \twocolglossary \renewcommand{\leftmark}{\glossaryname} { @@ -33,9 +36,9 @@ \chapter{Bibliography} \clearpage \input{xrefdelta} -\renewcommand{\glossaryname}{Cross references from ISO \CppXVII} -\renewcommand{\preglossaryhook}{All section labels from -ISO \CppXVII (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp}) +\renewcommand{\glossaryname}{Cross references from ISO \CppXVII{}} +\renewcommand{\preglossaryhook}{All clause and subclause labels from +ISO \CppXVII{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}) are present in this document, with the exceptions described below.\\} \renewcommand{\leftmark}{\glossaryname} { @@ -61,6 +64,15 @@ \chapter{Bibliography} \printindex[grammarindex] } +\clearpage +\renewcommand{\preindexhook}{} +\renewcommand{\indexname}{Index of library headers} +\renewcommand{\leftmark}{\indexname} +{ +\raggedright +\printindex[headerindex] +} + \clearpage \renewcommand{\preindexhook}{} \renewcommand{\indexname}{Index of library names} @@ -71,7 +83,7 @@ \chapter{Bibliography} } \clearpage -\renewcommand{\preindexhook}{The entries in this section are rough descriptions; exact +\renewcommand{\preindexhook}{The entries in this index are rough descriptions; exact specifications are at the indicated page in the general text.\\} \renewcommand{\indexname}{Index of implementation-defined behavior} \renewcommand{\leftmark}{\indexname} diff --git a/source/basic.tex b/source/basic.tex index 47346e411d..1ae3ad0626 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4,11 +4,11 @@ \gramSec[gram.basic]{Basic concepts} \pnum -\begin{note} This Clause presents the basic concepts of the \Cpp language. +\begin{note} This Clause presents the basic concepts of the \Cpp{} language. It explains the difference between an object and a name and how they relate to the value categories for expressions. It introduces the concepts of a -declaration and a definition and presents \Cpp's +declaration and a definition and presents \Cpp{}'s notion of type, scope, linkage, and storage duration. The mechanisms for starting and terminating a program are discussed. Finally, this Clause presents the @@ -27,7 +27,9 @@ \indextext{scope}% \indextext{linkage}% \indextext{region!declarative}% -An \defn{entity} is a value, object, reference, function, enumerator, type, +An \defn{entity} is a value, object, reference, +structured binding, +function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack. @@ -51,6 +53,13 @@ a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object. +\pnum +A \defn{local entity} is a variable with +automatic storage duration\iref{basic.stc.auto}, +a structured binding\iref{dcl.struct.bind} +whose corresponding variable is such an entity, +or the \tcode{*this} object\iref{expr.prim.this}. + \pnum Some names denote types or templates. In general, whenever a name is encountered it is necessary to determine whether that name denotes @@ -113,7 +122,7 @@ the \indextext{declaration!\idxcode{extern}}% \tcode{extern} specifier\iref{dcl.stc} or a -\grammarterm{linkage-specification}\footnote{Appearing inside the braced-enclosed +\grammarterm{linkage-specification}\footnote{Appearing inside the brace-enclosed \grammarterm{declaration-seq} in a \grammarterm{linkage-specification} does not affect whether a declaration is a definition.}\iref{dcl.link} and neither an \grammarterm{initializer} nor a @@ -206,20 +215,20 @@ \pnum \begin{note} \indextext{implementation-generated}% -In some circumstances, \Cpp implementations implicitly define the +In some circumstances, \Cpp{} implementations implicitly define the default constructor\iref{class.ctor}, copy constructor\iref{class.copy}, move constructor\iref{class.copy}, copy assignment operator\iref{class.copy}, move assignment operator\iref{class.copy}, -or destructor\iref{class.dtor} member functions. \end{note} +or destructor\iref{class.dtor} member functions. +\end{note} \begin{example} Given - \begin{codeblock} #include struct C { - std::string s; // \tcode{std::string} is the standard library class\iref{strings} + std::string s; // \tcode{std::string} is the standard library class\iref{strings} }; int main() { @@ -228,27 +237,26 @@ b = a; } \end{codeblock} - the implementation will implicitly define functions to make the definition of \tcode{C} equivalent to - \begin{codeblock} struct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast(x.s)) { } - // \tcode{: s(std::move(x.s)) \{ \}} + @\rlap{\normalfont\itshape //}@ : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast(x.s); return *this; } - // \tcode{\{ s = std::move(x.s); return *this; \}} + @\rlap{\normalfont\itshape //}@ { s = std::move(x.s); return *this; } ~C() { } }; \end{codeblock} \end{example} \pnum -\begin{note} A class name can also be implicitly declared by an +\begin{note} +A class name can also be implicitly declared by an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}. \end{note} @@ -269,8 +277,9 @@ variable, function, class type, enumeration type, or template. \pnum +\indextext{expression!potentially evaluated}% An expression is \defn{potentially evaluated} unless it is an -unevaluated operand\iref{expr} or a subexpression thereof. +unevaluated operand\iref{expr.prop} or a subexpression thereof. The set of \defn{potential results} of an expression \tcode{e} is defined as follows: \begin{itemize} @@ -305,12 +314,44 @@ \begin{codeblock} struct S { static const int x = 0; }; const int &f(const int &r); -int n = b ? (1, S::x) // \tcode{S::x} is not odr-used here - : f(S::x); // \tcode{S::x} is odr-used here, so a definition is required +int n = b ? (1, S::x) // \tcode{S::x} is not odr-used here + : f(S::x); // \tcode{S::x} is odr-used here, so a definition is required \end{codeblock} \end{example} \end{note} +\pnum +\indextext{function!named by an expression}% +A function is \defn{named by an expression} as follows: +\begin{itemize} +\item + A function whose name appears in an expression + is named by that expression + if it is the unique lookup result or the selected member + of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}), + unless it is a pure virtual function and either + its name is not explicitly qualified or + the expression forms a pointer to member\iref{expr.unary.op}. + \begin{note} This covers + taking the address of functions~(\ref{conv.func}, \ref{expr.unary.op}), + calls to named functions\iref{expr.call}, + operator overloading\iref{over}, + user-defined conversions\iref{class.conv.fct}, + allocation functions for placement \grammarterm{new-expression}{s}\iref{expr.new}, as well as + non-default initialization\iref{dcl.init}. + A constructor selected to copy or move an object of class type + is considered to be named by an expression + even if the call is actually elided by the implementation\iref{class.copy}. \end{note} +\item + An allocation or deallocation function for a class + is named by a \grammarterm{new-expression} + as specified in~\ref{expr.new} and~\ref{class.free}. +\item + A deallocation function for a class + is named by a delete expression + as specified in~\ref{expr.delete} and~\ref{class.free}. +\end{itemize} + \pnum A variable \tcode{x} whose name appears as a potentially-evaluated expression \tcode{ex} is \defn{odr-used} by \tcode{ex} unless @@ -320,31 +361,21 @@ and, if \tcode{x} is an object, \tcode{ex} is an element of the set of potential results of an expression \tcode{e}, where either the lvalue-to-rvalue conversion\iref{conv.lval} is applied to \tcode{e}, or \tcode{e} is -a discarded-value expression\iref{expr}. -\tcode{this} is odr-used if it appears as a potentially-evaluated expression +a discarded-value expression\iref{expr.prop}. + +\pnum +A structured binding is odr-used if it appears as a potentially-evaluated expression. + +\pnum +\tcode{*this} is odr-used if \tcode{this} appears as a potentially-evaluated expression (including as the result of the implicit transformation in the body of a non-static member function~(\ref{class.mfct.non-static})). + +\pnum A virtual member function is odr-used if it is not pure. -A function whose name appears as a potentially-evaluated -expression is odr-used if it is the unique lookup result or the selected -member of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}), -unless it is a pure virtual function and either -its name is not explicitly qualified or -the expression forms a pointer to member\iref{expr.unary.op}. -\begin{note} This covers calls to named -functions\iref{expr.call}, operator overloading\iref{over}, -user-defined conversions\iref{class.conv.fct}, allocation functions for -placement \grammarterm{new-expression}{s}\iref{expr.new}, as well as non-default -initialization\iref{dcl.init}. A constructor selected to copy or move an -object of class type is odr-used even if the -call is actually elided by the implementation\iref{class.copy}. \end{note} An allocation -or deallocation function for a class is odr-used by a \grammarterm{new-expression} -appearing in a potentially-evaluated expression as specified -in~\ref{expr.new} and~\ref{class.free}. A deallocation function for a -class is odr-used by a delete expression appearing in a -potentially-evaluated expression as specified in~\ref{expr.delete} -and~\ref{class.free}. A non-placement allocation or deallocation +A function is odr-used if it is named by a potentially-evaluated expression. +A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the definition of the destructor of that class, or by being selected by the @@ -353,6 +384,8 @@ to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.} + +\pnum An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified @@ -361,6 +394,45 @@ in~\ref{dcl.init}. A destructor for a class is odr-used if it is potentially invoked\iref{class.dtor}. +\pnum +A local entity\iref{basic} +is \defn{odr-usable} in a declarative region\iref{basic.scope.declarative} if: + +\begin{itemize} +\item the local entity is either +not \tcode{*this}, or +an enclosing class or non-lambda function parameter scope exists and, +if the innermost such scope is a function parameter scope, +it corresponds to a non-static member function, and +\item +for each intervening declarative region\iref{basic.scope.declarative} +between the point at which the entity is introduced and the region +(where \tcode{*this} is considered to be introduced +within the innermost enclosing class or non-lambda function definition scope), +either: +\begin{itemize} +\item the declarative region is a block scope, or +\item the declarative region is the function parameter scope of a \grammarterm{lambda-expression} +that has a \grammarterm{simple-capture} naming the entity or has a \grammarterm{capture-default}. +\end{itemize} +\end{itemize} + +If a local entity is odr-used +in a declarative region in which it is not odr-usable, +the program is ill-formed. +\begin{example} +\begin{codeblock} +void f(int n) { + [] { n = 1; }; // error, \tcode{n} is not odr-usable due to intervening lambda-expression + struct A { + void f() { n = 2; } // error, \tcode{n} is not odr-usable due to intervening function definition scope + }; + void g(int = n); // error, \tcode{n} is not odr-usable due to intervening function parameter scope + [&] { [n]{ return n; }; }; // OK +} +\end{codeblock} +\end{example} + \pnum Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program @@ -446,7 +518,7 @@ template specialization\iref{temp.over}, except that a name can refer to \begin{itemize} \item -a non-volatile \tcode{const} object with internal or no linkage if the object +a non-volatile const object with internal or no linkage if the object \begin{itemize} \item has the same literal type in all definitions of \tcode{D}, \item is initialized with a constant expression\iref{expr.const}, @@ -517,7 +589,15 @@ template definition\iref{temp.nondep}, and also to dependent names at the point of instantiation\iref{temp.dep}. If the definitions of \tcode{D} satisfy all these requirements, then the behavior is -as if there were a single definition of \tcode{D}. If the definitions of +as if there were a single definition of \tcode{D}. +\begin{note} +The entity is still declared in multiple translation units, and \ref{basic.link} +still applies to these declarations. In particular, +\grammarterm{lambda-expression}{s}\iref{expr.prim.lambda} +appearing in the type of \tcode{D} may result +in the different declarations having distinct types. +\end{note} +If the definitions of \tcode{D} do not satisfy these requirements, then the behavior is undefined.% \indextext{one-definition rule|)} @@ -604,6 +684,14 @@ also introduce a (possibly not visible) name into an enclosing namespace; these restrictions apply to both regions. \end{note} +\pnum +For a given declarative region \placeholder{R} +and a point \placeholder{P} outside \placeholder{R}, +the set of \defnx{intervening}{region!declarative!intervening} declarative regions +between \placeholder{P} and \placeholder{R} +comprises all declarative regions +that are or enclose \placeholder{R} and do not enclose \placeholder{P}. + \pnum \begin{note} The name lookup rules are summarized in~\ref{basic.lookup}. \end{note} @@ -687,7 +775,7 @@ \item for a declaration of the form \begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} +class-key \opt{attribute-specifier-seq} identifier \terminal{;} \end{ncbnf} the \grammarterm{identifier} is declared to be a @@ -768,23 +856,6 @@ declaration\iref{basic.scope.pdecl} and ends at the end of its block. A variable declared at block scope is a \defn{local variable}. -\pnum -\indextext{parameter!scope of}% -The potential scope of a function parameter name -(including one appearing in a -\grammarterm{lambda-declarator}) -or of a function-local predefined variable -in a function -definition\iref{dcl.fct.def} begins at its point of declaration. If -the function has a \grammarterm{function-try-block} the potential scope of -a parameter -or of a function-local predefined variable -ends at the end of the last associated handler, otherwise it ends -at the end of the outermost block of the function definition. A -parameter name shall not be redeclared in the outermost block of the -function definition nor in the outermost block of any handler associated -with a \grammarterm{function-try-block}. - \pnum \indextext{scope!exception declaration}% The name declared in an \grammarterm{exception-declaration} @@ -802,15 +873,31 @@ statement, any of the outermost blocks) of the controlled statement; see~\ref{stmt.select}. -\rSec2[basic.scope.proto]{Function prototype scope} +\rSec2[basic.scope.param]{Function parameter scope} \pnum -\indextext{scope!function prototype}% -\indextext{function prototype}% -In a function declaration, or in any function declarator except the -declarator of a function definition\iref{dcl.fct.def}, names of -parameters (if supplied) have function prototype scope, which terminates -at the end of the nearest enclosing function declarator. +\indextext{scope!function parameter}% +\indextext{scope!function prototype|see{scope, function parameter}}% +\indextext{parameter!scope of}% +A function parameter +(including one appearing in a +\grammarterm{lambda-declarator}) +or function-local predefined variable\iref{dcl.fct.def} +has \defn{function parameter scope}. +The potential scope of a parameter +or function-local predefined variable +begins at its point of declaration. If +the nearest enclosing function declarator +is not the declarator of a function definition, +the potential scope ends at the end of that function declarator. +Otherwise, if +the function has a \grammarterm{function-try-block} the potential scope +ends at the end of the last associated handler. +Otherwise the potential scope ends +at the end of the outermost block of the function definition. A +parameter name shall not be redeclared in the outermost block of the +function definition nor in the outermost block of any handler associated +with a \grammarterm{function-try-block}. \rSec2[basic.funscope]{Function scope} @@ -1147,7 +1234,28 @@ in~\ref{basic.lookup.argdep}. \begin{note} For purposes of determining (during parsing) whether an expression is a \grammarterm{postfix-expression} for a function call, the usual name lookup -rules apply. The rules in~\ref{basic.lookup.argdep} have no effect on +rules apply. +In some cases +a name followed by \tcode{<} is treated as a \grammarterm{template-name} +even though name lookup did not find a \grammarterm{template-name} +(see \ref{temp.names}). +For example, +\begin{codeblock} +int h; +void g(); +namespace N { + struct A {}; + template int f(T); + template int g(T); + template int h(T); +} + +int x = f(N::A()); // OK: lookup of \tcode{f} finds nothing, \tcode{f} treated as template name +int y = g(N::A()); // OK: lookup of \tcode{g} finds a function, \tcode{g} treated as template name +int z = h(N::A()); // error: \tcode{h<} does not begin a \grammarterm{template-id} +\end{codeblock} + +The rules in~\ref{basic.lookup.argdep} have no effect on the syntactic interpretation of an expression. For example, \begin{codeblock} @@ -1157,7 +1265,7 @@ friend void f(A &); operator int(); void g(A a) { - int i = f(a); // \tcode{f} is the typedef, not the friend function: equivalent to \tcode{int(a)} + int i = f(a); // \tcode{f} is the typedef, not the friend function: equivalent to \tcode{int(a)} } }; } @@ -1264,7 +1372,7 @@ \end{example} \begin{note} When looking for a prior declaration of a class -or function introduced by a \tcode{friend} declaration, scopes outside +or function introduced by a friend declaration, scopes outside of the innermost enclosing namespace scope are not considered; see~\ref{namespace.memdef}. \end{note} \begin{note} \ref{basic.scope.class} further describes the restrictions on the use of names in a class @@ -1344,16 +1452,16 @@ definitions. \end{note} \pnum -Name lookup for a name used in the definition of a \tcode{friend} +Name lookup for a name used in the definition of a friend function\iref{class.friend} defined inline in the class granting friendship shall proceed as described for lookup in member function -definitions. If the \tcode{friend} function is not defined in the class -granting friendship, name lookup in the \tcode{friend} function +definitions. If the friend function is not defined in the class +granting friendship, name lookup in the friend function definition shall proceed as described for lookup in namespace member function definitions. \pnum -In a \tcode{friend} declaration naming a member function, a name used in +In a friend declaration naming a member function, a name used in the function declarator and not part of a \grammarterm{template-argument} in the \grammarterm{declarator-id} is first looked up in the scope of the member function's class\iref{class.member.lookup}. If it is not found, @@ -1573,10 +1681,10 @@ \item Any \grammarterm{using-directive}{s} in the associated namespace are ignored. -\item Any namespace-scope friend functions or friend function templates +\item Any namespace-scope friend functions or friend function templates\iref{class.friend} declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary -lookup\iref{class.friend}. +lookup\iref{namespace.memdef}. \item All names except those of (possibly overloaded) functions and function templates are ignored. @@ -1664,7 +1772,7 @@ \grammarterm{qualified-id} of the form: \begin{ncbnf} -nested-name-specifier\opt class-name \terminal{::} \terminal{\tilde} class-name +\opt{nested-name-specifier} class-name \terminal{::} \terminal{\~} class-name \end{ncbnf} the second \grammarterm{class-name} is looked up in the same scope as the @@ -2024,7 +2132,7 @@ following form: \begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} +class-key \opt{attribute-specifier-seq} identifier \terminal{;} \end{ncbnf} the \grammarterm{identifier} is looked up according @@ -2039,7 +2147,7 @@ form: \begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} +class-key \opt{attribute-specifier-seq} identifier \terminal{;} \end{ncbnf} the \grammarterm{elaborated-type-specifier} is a declaration that @@ -2057,8 +2165,7 @@ \begin{codeblock} struct Node { struct Node* Next; // OK: Refers to \tcode{Node} at global scope - struct Data* Data; // OK: Declares type \tcode{Data} - // at global scope and member \tcode{Data} + struct Data* Data; // OK: Declares type \tcode{Data} at global scope and member \tcode{Data} }; struct Data { @@ -2205,7 +2312,7 @@ \begin{bnf} \nontermdef{translation-unit}\br - declaration-seq\opt + \opt{declaration-seq} \end{bnf} \pnum @@ -2338,7 +2445,10 @@ \indextext{linkage!no}% Names not covered by these rules have no linkage. Moreover, except as noted, a name declared at block scope\iref{basic.scope.block} has no -linkage. A type is said to have linkage if and only if: +linkage. + +\pnum +A type is said to have linkage if and only if: \begin{itemize} \item it is a class or enumeration type that is named (or has a name for linkage purposes\iref{dcl.typedef}) and the name has linkage; or @@ -2364,9 +2474,6 @@ \begin{itemize} \item the entity has C language linkage\iref{dcl.link}, or -\item the entity is declared within an unnamed -namespace\iref{namespace.def}, or - \item the entity is not odr-used\iref{basic.def.odr} or is defined in the same translation unit. \end{itemize} @@ -2429,429 +2536,546 @@ identity does not require a diagnostic. \pnum -\begin{note} Linkage to non-\Cpp declarations can be achieved using a +\begin{note} Linkage to non-\Cpp{} declarations can be achieved using a \grammarterm{linkage-specification}\iref{dcl.link}. \end{note}% \indextext{linkage|)} -\rSec1[basic.start]{Start and termination} +\rSec1[basic.memobj]{Memory and objects} -\rSec2[basic.start.main]{\tcode{main} function} -\indextext{\idxcode{main} function|(} +\rSec2[intro.memory]{Memory model} \pnum -\indextext{program!start|(}% -A program shall contain a global function called \tcode{main}. -Executing a program starts a main thread of execution~(\ref{intro.multithread}, \ref{thread.threads}) -in which the \tcode{main} function is invoked, -and in which variables of static storage duration -might be initialized\iref{basic.start.static} and destroyed\iref{basic.start.term}. -It is \impldef{defining \tcode{main} in freestanding environment} -whether a program in a freestanding environment is required to define a \tcode{main} -function. \begin{note} In a freestanding environment, start-up and termination is -\impldef{start-up and termination in freestanding environment}; start-up contains the -execution of constructors for objects of namespace scope with static storage duration; -termination contains the execution of destructors for objects with static storage -duration. \end{note} +\indextext{memory model|(}% +The fundamental storage unit in the \Cpp{} memory model is the +\defn{byte}. +A byte is at least large enough to contain any member of the basic +\indextext{character set!basic execution}% +execution character set\iref{lex.charset} +and the eight-bit code units of the Unicode UTF-8 encoding form +and is composed of a contiguous sequence of +bits,\footnote{The number of bits in a byte is reported by the macro +\tcode{CHAR_BIT} in the header \tcode{}.} +the number of which is \impldef{bits in a byte}. The least +significant bit is called the \defn{low-order bit}; the most +significant bit is called the \defn{high-order bit}. The memory +available to a \Cpp{} program consists of one or more sequences of +contiguous bytes. Every byte has a unique address. \pnum -An implementation shall not predefine the \tcode{main} function. This -function shall not be overloaded. Its type shall have \Cpp language linkage -and it shall have a declared return type of type -\tcode{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. -\indextext{\idxcode{main} function!implementation-defined parameters to}% -An implementation shall allow both -\begin{itemize} -\item a function of \tcode{()} returning \tcode{int} and -\item a function of \tcode{(int}, pointer to pointer to \tcode{char)} returning \tcode{int} -\end{itemize} - -\indextext{\idxcode{argc}}% -\indextext{\idxcode{argv}}% -as the type of \tcode{main}\iref{dcl.fct}. -\indextext{\idxcode{main} function!parameters to}% -\indextext{environment!program}% -In the latter form, for purposes of exposition, the first function -parameter is called \tcode{argc} and the second function parameter is -called \tcode{argv}, where \tcode{argc} shall be the number of -arguments passed to the program from the environment in which the -program is run. If -\tcode{argc} is nonzero these arguments shall be supplied in -\tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial -characters of null-terminated multibyte strings (\ntmbs{}s)\iref{multibyte.strings} -and \tcode{argv[0]} shall be the pointer to -the initial character of a \ntmbs that represents the name used to -invoke the program or \tcode{""}. The value of \tcode{argc} shall be -non-negative. The value of \tcode{argv[argc]} shall be 0. \begin{note} It -is recommended that any further (optional) parameters be added after -\tcode{argv}. \end{note} +\begin{note} The representation of types is described +in~\ref{basic.types}. \end{note} \pnum -The function \tcode{main} shall not be used within -a program. -\indextext{\idxcode{main} function!implementation-defined linkage of}% -The linkage\iref{basic.link} of \tcode{main} is -\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as -deleted or that declares \tcode{main} to be -\tcode{inline}, \tcode{static}, or \tcode{constexpr} is ill-formed. -The \tcode{main} function shall not be declared with a -\grammarterm{linkage-specification}\iref{dcl.link}. A program that -declares a variable \tcode{main} at global scope or that declares the name -\tcode{main} with C language linkage (in any namespace) is ill-formed. -The name \tcode{main} is -not otherwise reserved. \begin{example} Member functions, classes, and -enumerations can be called \tcode{main}, as can entities in other -namespaces. \end{example} +A \defn{memory location} is either an object of scalar type or a maximal +sequence of adjacent bit-fields all having nonzero width. \begin{note} Various +features of the language, such as references and virtual functions, might +involve additional memory locations that are not accessible to programs but are +managed by the implementation. \end{note} Two or more threads of +execution\iref{intro.multithread} can access separate memory +locations without interfering with each other. \pnum -\indextext{\idxcode{exit}}% -\indexlibrary{\idxcode{exit}}% -\indextext{termination!program}% -Terminating the program -without leaving the current block (e.g., by calling the function -\tcode{std::exit(int)}\iref{support.start.term}) does not destroy any -objects with automatic storage duration\iref{class.dtor}. If -\tcode{std::exit} is called to end a program during the destruction of -an object with static or thread storage duration, the program has undefined -behavior. +\begin{note} Thus a bit-field and an adjacent non-bit-field are in separate memory +locations, and therefore can be concurrently updated by two threads of execution +without interference. The same applies to two bit-fields, if one is declared +inside a nested struct declaration and the other is not, or if the two are +separated by a zero-length bit-field declaration, or if they are separated by a +non-bit-field declaration. It is not safe to concurrently update two bit-fields +in the same struct if all fields between them are also bit-fields of nonzero +width. \end{note} \pnum -\indextext{termination!program}% -\indextext{\idxcode{main} function!return from}% -A return statement in \tcode{main} has the effect of leaving the main -function (destroying any objects with automatic storage duration) and -calling \tcode{std::exit} with the return value as the argument. -If control flows off the end of -the \grammarterm{compound-statement} of \tcode{main}, -the effect is equivalent to a \tcode{return} with operand \tcode{0} -(see also \ref{except.handle}). -\indextext{\idxcode{main} function|)} +\begin{example} A structure declared as -\rSec2[basic.start.static]{Static initialization} +\begin{codeblock} +struct { + char a; + int b:5, + c:11, + :0, + d:8; + struct {int ee:8;} e; +} +\end{codeblock} -\pnum -\indextext{initialization}% -\indextext{initialization!static and thread}% -Variables with static storage duration -are initialized as a consequence of program initiation. Variables with -thread storage duration are initialized as a consequence of thread execution. -Within each of these phases of initiation, initialization occurs as follows. +contains four separate memory locations: The member \tcode{a} and bit-fields +\tcode{d} and \tcode{e.ee} are each separate memory locations, and can be +modified concurrently without interfering with each other. The bit-fields +\tcode{b} and \tcode{c} together constitute the fourth memory location. The +bit-fields \tcode{b} and \tcode{c} cannot be concurrently modified, but +\tcode{b} and \tcode{a}, for example, can be. \end{example}% +\indextext{memory model|)} -\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. -\indextext{initialization!runtime}% -If constant initialization is not performed, a variable with static -storage duration\iref{basic.stc.static} or thread storage -duration\iref{basic.stc.thread} is zero-initialized\iref{dcl.init}. -Together, zero-initialization and constant initialization are called -\indextext{initialization!dynamic}% -\defn{static initialization}; -all other initialization is \defn{dynamic initialization}. -All static initialization strongly happens before\iref{intro.races} -any dynamic initialization. -\begin{note} The dynamic initialization of non-local variables is described -in~\ref{basic.start.dynamic}; that of local static variables is described -in~\ref{stmt.dcl}. \end{note} +\rSec2[intro.object]{Object model} \pnum -An implementation is permitted to perform the initialization of a -variable with static or thread storage duration as a static -initialization even if such initialization is not required to be done -statically, provided that +\indextext{object model|(}% +The constructs in a \Cpp{} program create, destroy, refer to, access, and +manipulate objects. +An \defn{object} is created +by a definition\iref{basic.def}, +by a \grammarterm{new-expression}\iref{expr.new}, +when implicitly changing the active member of a union\iref{class.union}, +or +when a temporary object is created~(\ref{conv.rval}, \ref{class.temporary}). +An object occupies a region of storage +in its period of construction\iref{class.cdtor}, +throughout its lifetime\iref{basic.life}, +and +in its period of destruction\iref{class.cdtor}. +\begin{note} A function is not an object, regardless of whether or not it +occupies storage in the way that objects do. \end{note} +The properties of an +object are determined when the object is created. An object can have a +name\iref{basic}. An object has a storage +duration\iref{basic.stc} which influences its +lifetime\iref{basic.life}. An object has a +type\iref{basic.types}. +Some objects are +polymorphic\iref{class.virtual}; the implementation +generates information associated with each such object that makes it +possible to determine that object's type during program execution. For +other objects, the interpretation of the values found therein is +determined by the type of the \grammarterm{expression}{s}\iref{expr.compound} +used to access them. + +\pnum +\indextext{subobject}% +Objects can contain other objects, called \defnx{subobjects}{subobject}. +A subobject can be +a \defn{member subobject}\iref{class.mem}, a \defn{base class subobject}\iref{class.derived}, +or an array element. +\indextext{object!complete}% +An object that is not a subobject of any other object is called a \defn{complete +object}. +If an object is created +in storage associated with a member subobject or array element \placeholder{e} +(which may or may not be within its lifetime), +the created object +is a subobject of \placeholder{e}'s containing object if: \begin{itemize} \item -the dynamic version of the initialization does not change the -value of any other object of static or thread storage duration -prior to its initialization, and - +the lifetime of \placeholder{e}'s containing object has begun and not ended, and \item -the static version of the initialization produces the same value -in the initialized variable as would be produced by the dynamic -initialization if all variables not required to be initialized statically -were initialized dynamically. +the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and +\item +the new object is of the same type as \placeholder{e} (ignoring cv-qualification). \end{itemize} \begin{note} -As a consequence, if the initialization of an object \tcode{obj1} refers to an -object \tcode{obj2} of namespace scope potentially requiring dynamic initialization and defined -later in the same translation unit, it is unspecified whether the value of \tcode{obj2} used -will be the value of the fully initialized \tcode{obj2} (because \tcode{obj2} was statically -initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example, +If the subobject contains a reference member or a \tcode{const} subobject, +the name of the original subobject cannot be used to access the new object\iref{basic.life}. +\end{note} +\begin{example} \begin{codeblock} -inline double fd() { return 1.0; } -extern double d1; -double d2 = d1; // unspecified: - // may be statically initialized to \tcode{0.0} or - // dynamically initialized to \tcode{0.0} if \tcode{d1} is - // dynamically initialized, or \tcode{1.0} otherwise -double d1 = fd(); // may be initialized statically or dynamically to \tcode{1.0} +struct X { const int n; }; +union U { X x; float f; }; +void tong() { + U u = {{ 1 }}; + u.f = 5.f; // OK, creates new subobject of \tcode{u}\iref{class.union} + X *p = new (&u.x) X {2}; // OK, creates new subobject of \tcode{u} + assert(p->n == 2); // OK + assert(*std::launder(&u.x.n) == 2); // OK + assert(u.x.n == 2); // undefined behavior, \tcode{u.x} does not name new subobject +} \end{codeblock} +\end{example} + +\pnum +\indextext{object!providing storage for}% +If a complete object is created\iref{expr.new} +in storage associated with another object \placeholder{e} +of type ``array of $N$ \tcode{unsigned char}'' or +of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, +that array \defn{provides storage} +for the created object if: +\begin{itemize} +\item +the lifetime of \placeholder{e} has begun and not ended, and +\item +the storage for the new object fits entirely within \placeholder{e}, and +\item +there is no smaller array object that satisfies these constraints. +\end{itemize} +\begin{note} +If that portion of the array +previously provided storage for another object, +the lifetime of that object ends +because its storage was reused\iref{basic.life}. \end{note} +\begin{example} +\begin{codeblock} +template +struct AlignedUnion { + alignas(T...) unsigned char data[max(sizeof(T)...)]; +}; +int f() { + AlignedUnion au; + int *p = new (au.data) int; // OK, \tcode{au.data} provides storage + char *c = new (au.data) char(); // OK, ends lifetime of \tcode{*p} + char *d = new (au.data + 1) char(); + return *c + *d; // OK +} -\rSec2[basic.start.dynamic]{Dynamic initialization of non-local variables} +struct A { unsigned char a[32]; }; +struct B { unsigned char b[16]; }; +A a; +B *b = new (a.a + 8) B; // \tcode{a.a} provides storage for \tcode{*b} +int *p = new (b->b + 4) int; // \tcode{b->b} provides storage for \tcode{*p} + // \tcode{a.a} does not provide storage for \tcode{*p} (directly), + // but \tcode{*p} is nested within \tcode{a} (see below) +\end{codeblock} +\end{example} \pnum -\indextext{initialization!dynamic non-local}% -\indextext{start!program}% -\indextext{initialization!order of}% -Dynamic initialization of a non-local variable with static storage duration is -unordered if the variable is an implicitly or explicitly instantiated -specialization, is partially-ordered if the variable -is an inline variable that is not an implicitly or explicitly instantiated -specialization, and otherwise is ordered. -\begin{note} An explicitly specialized non-inline static data member or -variable template specialization has ordered initialization.\end{note} +\indextext{object!nested within}% +An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if: +\begin{itemize} +\item +\placeholder{a} is a subobject of \placeholder{b}, or +\item +\placeholder{b} provides storage for \placeholder{a}, or +\item +there exists an object \placeholder{c} +where \placeholder{a} is nested within \placeholder{c}, +and \placeholder{c} is nested within \placeholder{b}. +\end{itemize} \pnum -Dynamic initialization of non-local variables \tcode{V} and \tcode{W} -with static storage duration are ordered as follows: +For every object \tcode{x}, there is some object called the +\defn{complete object of} \tcode{x}, determined as follows: \begin{itemize} \item -If \tcode{V} and \tcode{W} have -ordered initialization and \tcode{V} is defined before \tcode{W} within -a single translation unit, the initialization of \tcode{V} is sequenced -before the initialization of \tcode{W}. +If \tcode{x} is a complete object, then the complete object +of \tcode{x} is itself. \item -If \tcode{V} has partially-ordered initialization, \tcode{W} does not have -unordered initialization, and \tcode{V} is defined before \tcode{W} in -every translation unit in which \tcode{W} is defined, then -\begin{itemize} -\item -if the program starts a thread\iref{intro.multithread} -other than the main thread\iref{basic.start.main}, -the initialization of \tcode{V} -strongly happens before -the initialization of \tcode{W}; -\item -otherwise, -the initialization of \tcode{V} -is sequenced before -the initialization of \tcode{W}. +Otherwise, the complete object of \tcode{x} is the complete object +of the (unique) object that contains \tcode{x}. \end{itemize} -\item -Otherwise, if the program starts a thread -other than the main thread -before either \tcode{V} or \tcode{W} is initialized, -it is unspecified in which threads -the initializations of \tcode{V} and \tcode{W} occur; -the initializations are unsequenced if they occur in the same thread. - -\item -Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced. -\end{itemize} -\begin{note} -This definition permits initialization of a sequence of -ordered variables concurrently with another sequence. -\end{note} +\pnum +If a complete object, a data member\iref{class.mem}, or an array element is of +class type, its type is considered the \defn{most derived +class}, to distinguish it from the class type of any base class subobject; +an object of a most derived class type or of a non-class type is called a +\defn{most derived object}. \pnum -\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% -A \defnx{non-initialization odr-use}{odr-use!non-initialization} -is an odr-use\iref{basic.def.odr} not caused directly or indirectly by -the initialization of a non-local static or thread storage duration variable. +\indextext{most derived object!bit-field}% +Unless it is a bit-field\iref{class.bit}, a most derived object shall have a +nonzero size and shall occupy one or more bytes of storage. Base class +subobjects may have zero size. An object of trivially copyable or +standard-layout type\iref{basic.types} shall occupy contiguous bytes of +storage. \pnum -\indextext{evaluation!unspecified order of}% -It is \impldef{dynamic initialization of static variables before \tcode{main}} -whether the dynamic initialization of a -non-local non-inline variable with static storage duration -is sequenced before the first statement of \tcode{main} or is deferred. -If it is deferred, it strongly happens before -any non-initialization odr-use -of any non-inline function or non-inline variable -defined in the same translation unit as the variable to be initialized.% -\footnote{A non-local variable with static storage duration -having initialization -with side effects is initialized in this case, -even if it is not itself odr-used~(\ref{basic.def.odr}, \ref{basic.stc.static}).} -It is \impldef{threads and program points at which deferred dynamic initialization is performed} -in which threads and at which points in the program such deferred dynamic initialization occurs. -\begin{note} -Such points should be chosen in a way that allows the programmer to avoid deadlocks. -\end{note} +\indextext{most derived object!bit-field}% +\indextext{most derived object!zero size subobject}% +Unless an object is a bit-field or a base class subobject of zero size, the +address of that object is the address of the first byte it occupies. +Two objects \placeholder{a} and \placeholder{b} +with overlapping lifetimes +that are not bit-fields +may have the same address +if one is nested within the other, +or +if at least one is a base class subobject of zero size +and they are of different types; +otherwise, they have distinct addresses.\footnote{Under the ``as-if'' rule an +implementation is allowed to store two objects at the same machine address or +not store an object at all if the program cannot observe the +difference\iref{intro.execution}.} \begin{example} \begin{codeblock} -// - File 1 - -#include "a.h" -#include "b.h" -B b; -A::A(){ - b.Use(); -} - -// - File 2 - -#include "a.h" -A a; - -// - File 3 - -#include "a.h" -#include "b.h" -extern A a; -extern B b; - -int main() { - a.Use(); - b.Use(); -} +static const char test1 = 'x'; +static const char test2 = 'x'; +const bool b = &test1 != &test2; // always \tcode{true} \end{codeblock} - -It is \impldef{dynamic initialization of static variables before \tcode{main}} -whether either \tcode{a} or \tcode{b} is -initialized before \tcode{main} is entered or whether the -initializations are delayed until \tcode{a} is first odr-used in -\tcode{main}. In particular, if \tcode{a} is initialized before -\tcode{main} is entered, it is not guaranteed that \tcode{b} will be -initialized before it is odr-used by the initialization of \tcode{a}, that -is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized -at some point after the first statement of \tcode{main}, \tcode{b} will -be initialized prior to its use in \tcode{A::A}. \end{example} - -\pnum -It is \impldef{dynamic initialization of static inline variables before \tcode{main}} -whether the dynamic initialization of a -non-local inline variable with static storage duration -is sequenced before the first statement of \tcode{main} or is deferred. -If it is deferred, it strongly happens before -any non-initialization odr-use -of that variable. -It is \impldef{threads and program points at which deferred dynamic initialization is performed} -in which threads and at which points in the program such deferred dynamic initialization occurs. - -\pnum -It is \impldef{dynamic initialization of thread-local variables before entry} -whether the dynamic initialization of a -non-local non-inline variable with thread storage duration -is sequenced before the first statement of the initial function of a thread or is deferred. -If it is deferred, -the initialization associated with the entity for thread \placeholder{t} -is sequenced before the first non-initialization odr-use by \placeholder{t} -of any non-inline variable with thread storage duration -defined in the same translation unit as the variable to be initialized. -It is \impldef{threads and program points at which deferred dynamic initialization is performed} -in which threads and at which points in the program such deferred dynamic initialization occurs. - -\pnum -If the initialization of a non-local variable with static or thread storage duration -exits via -an exception, \tcode{std::terminate} is called\iref{except.terminate}.% -\indextext{program!start|)} - -\rSec2[basic.start.term]{Termination} +\end{example} \pnum -\indextext{program!termination|(}% -\indextext{object!destructor static}% -\indextext{\idxcode{main} function!return from}% -Destructors\iref{class.dtor} for initialized objects -(that is, objects whose lifetime\iref{basic.life} has begun) -with static storage duration, -and functions registered with \tcode{std::atexit}, -are called as part of a call to -\indextext{\idxcode{exit}}% -\indexlibrary{\idxcode{exit}}% -\tcode{std::exit}\iref{support.start.term}. -The call to \tcode{std::exit} is sequenced before -the invocations of the destructors and the registered functions. \begin{note} -Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. -\end{note} +\Cpp{} provides a variety of fundamental types and several ways of composing +new types from existing types\iref{basic.types}. +\end{note}% +\indextext{object model|)} -\pnum -Destructors for initialized objects with thread storage duration within a given thread -are called as a result of returning from the initial function of that thread and as a -result of that thread calling \tcode{std::exit}. -The completions of the destructors for all initialized objects with thread storage -duration within that thread strongly happen before the initiation of the destructors of -any object with static storage duration. +\rSec2[basic.life]{Object lifetime} \pnum -If the completion of the constructor or dynamic initialization of an object with static -storage duration strongly happens before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. -If the completion of the constructor or dynamic initialization of an object with thread -storage duration is sequenced before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. -If an object is -initialized statically, the object is destroyed in the same order as if -the object was dynamically initialized. For an object of array or class -type, all subobjects of that object are destroyed before any block-scope -object with static storage duration initialized during the construction -of the subobjects is destroyed. -If the destruction of an object with static or thread storage duration -exits via an exception, -\tcode{std::terminate} is called\iref{except.terminate}. +\indextext{object lifetime|(}% +The \defn{lifetime} of an object or reference is a runtime property of the +object or reference. +An object is said to have \defnx{non-vacuous initialization}{initialization!non-vacuous} if it is of a class or +aggregate type and it or one of its subobjects is initialized by a constructor +other than a trivial default constructor. \begin{note} Initialization by a +trivial copy/move constructor is non-vacuous initialization. \end{note} +The lifetime of an object of type \tcode{T} begins when: +\begin{itemize} +\item storage with the proper alignment and size for type \tcode{T} is +obtained, and +\item if the object has non-vacuous initialization, its initialization is complete, +\end{itemize} +except that if the object is a union member or subobject thereof, +its lifetime only begins if that union member is the +initialized member in the union~(\ref{dcl.init.aggr}, \ref{class.base.init}), +or as described in \ref{class.union}. +The lifetime of an object \placeholder{o} of type \tcode{T} ends when: +\begin{itemize} +\item if \tcode{T} is a class type with a non-trivial +destructor\iref{class.dtor}, the destructor call starts, or +\item the storage which the object occupies is released, +or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. +\end{itemize} \pnum -If a function contains a block-scope object of static or thread storage duration that has been -destroyed and the function is called during the destruction of an object with static or -thread storage duration, the program has undefined behavior if the flow of control -passes through the definition of the previously destroyed block-scope object. Likewise, the -behavior is undefined if the block-scope object is used indirectly (i.e., through a -pointer) after its destruction. +The lifetime of a reference begins when its initialization is complete. +The lifetime of a reference ends as if it were a scalar object. \pnum -\indextext{\idxcode{atexit}}% -\indexlibrary{\idxcode{atexit}}% -If the completion of the initialization of an object with static storage -duration strongly happens before a call to \tcode{std::atexit}~(see -\tcode{}, \ref{support.start.term}), the call to the function passed to -\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a -call to \tcode{std::atexit} strongly happens before the completion of the initialization of -an object with static storage duration, the call to the destructor for the -object is sequenced before the call to the function passed to \tcode{std::atexit}. If a -call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the -call to the function passed to the second \tcode{std::atexit} call is sequenced before -the call to the function passed to the first \tcode{std::atexit} call. +\begin{note} \ref{class.base.init} +describes the lifetime of base and member subobjects. \end{note} \pnum -If there is a use of a standard library object or function not permitted within signal -handlers\iref{support.runtime} that does not happen before\iref{intro.multithread} -completion of destruction of objects with static storage duration and execution of -\tcode{std::atexit} registered functions\iref{support.start.term}, the program has -undefined behavior. \begin{note} If there is a use of an object with static storage -duration that does not happen before the object's destruction, the program has undefined -behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from -\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These -requirements permit thread managers as static-storage-duration objects. \end{note} +The properties ascribed to objects and references throughout this document +apply for a given object or reference only during its lifetime. \begin{note} +In particular, before the lifetime of an object starts and after its +lifetime ends there are significant restrictions on the use of the +object, as described below, in~\ref{class.base.init} and +in~\ref{class.cdtor}. Also, the behavior of an object under construction +and destruction might not be the same as the behavior of an object whose +lifetime has started and not ended. \ref{class.base.init} +and~\ref{class.cdtor} describe the behavior of objects during the +construction and destruction phases. \end{note} \pnum -\indextext{\idxcode{abort}}% -\indexlibrary{\idxcode{abort}}% -\indextext{termination!program}% -Calling the function \tcode{std::abort()} declared in -\indextext{\idxhdr{cstdlib}}% -\tcode{} terminates the program without executing any destructors -and without calling -the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% -\indextext{program!termination|)} - -\rSec1[basic.stc]{Storage duration} +A program may end the lifetime of any object by reusing the storage +which the object occupies or by explicitly calling the destructor for an +object of a class type with a non-trivial destructor. For an object of a +class type with a non-trivial destructor, the program is not required to +call the destructor explicitly before the storage which the object +occupies is reused or released; however, if there is no explicit call to +the destructor or if a \grammarterm{delete-expression}\iref{expr.delete} +is not used to release the storage, the destructor shall not be +implicitly called and any program that depends on the side effects +produced by the destructor has undefined behavior. \pnum -\indextext{storage duration|(}% -The \defn{storage duration} is the property of an object that defines the minimum -potential lifetime of the storage containing the object. The storage -duration is determined by the construct used to create the object and is -one of the following: - +Before the lifetime of an object has started but after the storage which +the object will occupy has been allocated\footnote{For example, before the +construction of a global object +that is initialized via a user-provided constructor\iref{class.cdtor}.} +or, after the lifetime of an object has ended and before the storage +which the object occupied is reused or released, any pointer that represents the address of +the storage location where the object will be or was located may be +used but only in limited ways. +For an object under construction or destruction, see~\ref{class.cdtor}. +Otherwise, such +a pointer refers to allocated +storage\iref{basic.stc.dynamic.allocation}, and using the pointer as +if the pointer were of type \tcode{void*}, is +well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in +limited ways, as described below. The +program has undefined behavior if: \begin{itemize} -\item static storage duration -\item thread storage duration -\item automatic storage duration -\item dynamic storage duration -\end{itemize} - -\pnum +\item + the object will be or was of a class type with a non-trivial destructor + and the pointer is used as the operand of a \grammarterm{delete-expression}, +\item + the pointer is used to access a non-static data member or call a + non-static member function of the object, or +\item + the pointer is implicitly converted\iref{conv.ptr} to a pointer + to a virtual base class, or +\item + the pointer is used as the operand of a + \tcode{static_cast}\iref{expr.static.cast}, except when the conversion + is to pointer to \cv{}~\tcode{void}, or to pointer to \cv{}~\tcode{void} + and subsequently to pointer to + \cv{}~\tcode{char}, + \cv{}~\tcode{unsigned char}, or + \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or +\item + the pointer is used as the operand of a + \tcode{dynamic_cast}\iref{expr.dynamic.cast}. +\end{itemize} +\begin{example} +\begin{codeblock} +#include + +struct B { + virtual void f(); + void mutate(); + virtual ~B(); +}; + +struct D1 : B { void f(); }; +struct D2 : B { void f(); }; + +void B::mutate() { + new (this) D2; // reuses storage --- ends the lifetime of \tcode{*this} + f(); // undefined behavior + ... = this; // OK, \tcode{this} points to valid memory +} + +void g() { + void* p = std::malloc(sizeof(D1) + sizeof(D2)); + B* pb = new (p) D1; + pb->mutate(); + *pb; // OK: \tcode{pb} points to valid memory + void* q = pb; // OK: \tcode{pb} points to valid memory + pb->f(); // undefined behavior, lifetime of \tcode{*pb} has ended +} +\end{codeblock} +\end{example} + +\pnum +Similarly, before the lifetime of an object has started but after the +storage which the object will occupy has been allocated or, after the +lifetime of an object has ended and before the storage which the object +occupied is reused or released, any glvalue that refers to the original +object may be used but only in limited ways. +For an object under construction or destruction, see~\ref{class.cdtor}. +Otherwise, such +a glvalue refers to +allocated storage\iref{basic.stc.dynamic.allocation}, and using the +properties of the glvalue that do not depend on its value is +well-defined. The program has undefined behavior if: +\begin{itemize} +\item the glvalue is used to access the object, or +\item the glvalue is used to call a non-static member function of the object, or +\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or +\item the glvalue is used as the operand of a +\tcode{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of +\tcode{typeid}. +\end{itemize} + +\pnum +If, after the lifetime of an object has ended and before the storage +which the object occupied is reused or released, a new object is created +at the storage location which the original object occupied, a pointer +that pointed to the original object, a reference that referred to the +original object, or the name of the original object will automatically +refer to the new object and, once the lifetime of the new object has +started, can be used to manipulate the new object, if: +\begin{itemize} +\item the storage for the new object exactly overlays the storage +location which the original object occupied, and + +\item the new object is of the same type as the original object +(ignoring the top-level cv-qualifiers), and + +\item the type of the original object is not const-qualified, and, if a +class type, does not contain any non-static data member whose type is +const-qualified or a reference type, and + +\item the original object was a most derived object\iref{intro.object} +of type \tcode{T} and the new object is a most derived object of type +\tcode{T} (that is, they are not base class subobjects). +\end{itemize} +\begin{example} +\begin{codeblock} +struct C { + int i; + void f(); + const C& operator=( const C& ); +}; + +const C& C::operator=( const C& other) { + if ( this != &other ) { + this->~C(); // lifetime of \tcode{*this} ends + new (this) C(other); // new object of type \tcode{C} created + f(); // well-defined + } + return *this; +} + +C c1; +C c2; +c1 = c2; // well-defined +c1.f(); // well-defined; \tcode{c1} refers to a new object of type \tcode{C} +\end{codeblock} +\end{example} +\begin{note} +If these conditions are not met, +a pointer to the new object can be obtained from +a pointer that represents the address of its storage +by calling \tcode{std::launder}\iref{support.dynamic}. +\end{note} + +\pnum +If a program ends the lifetime of an object of type \tcode{T} with +static\iref{basic.stc.static}, thread\iref{basic.stc.thread}, +or automatic\iref{basic.stc.auto} +storage duration and if \tcode{T} has a non-trivial destructor,\footnote{That +is, an object for which a destructor will be called +implicitly---upon exit from the block for an object with +automatic storage duration, upon exit from the thread for an object with +thread storage duration, or upon exit from the program for an object +with static storage duration.} +the program must ensure that an object of the original type occupies +that same storage location when the implicit destructor call takes +place; otherwise the behavior of the program is undefined. This is true +even if the block is exited with an exception. \begin{example} + +\begin{codeblock} +class T { }; +struct B { + ~B(); +}; + +void h() { + B b; + new (&b) T; +} // undefined behavior at block exit +\end{codeblock} +\end{example} + +\pnum +Creating a new object within the storage that a const complete +object with static, thread, or automatic storage duration occupies, +or within the storage that such a const object used to occupy before +its lifetime ended, results in undefined behavior. +\begin{example} +\begin{codeblock} +struct B { + B(); + ~B(); +}; + +const B b; + +void h() { + b.~B(); + new (const_cast(&b)) const B; // undefined behavior +} +\end{codeblock} +\end{example} + +\pnum +In this subclause, ``before'' and ``after'' refer to the ``happens before'' +relation\iref{intro.multithread}. \begin{note} Therefore, undefined behavior results +if an object that is being constructed in one thread is referenced from another +thread without adequate synchronization. \end{note}% +\indextext{object lifetime|)} + +\rSec2[basic.stc]{Storage duration} + +\pnum +\indextext{storage duration|(}% +The \defn{storage duration} is the property of an object that defines the minimum +potential lifetime of the storage containing the object. The storage +duration is determined by the construct used to create the object and is +one of the following: + +\begin{itemize} +\item static storage duration +\item thread storage duration +\item automatic storage duration +\item dynamic storage duration +\end{itemize} + +\pnum \indextext{storage duration!static}% \indextext{storage duration!thread}% \indextext{storage duration!automatic}% @@ -2879,7 +3103,7 @@ copying an invalid pointer value causes a system-generated runtime fault.} -\rSec2[basic.stc.static]{Static storage duration} +\rSec3[basic.stc.static]{Static storage duration} \pnum \indextext{storage duration!static}% @@ -2907,7 +3131,7 @@ The keyword \tcode{static} applied to a class data member in a class definition gives the data member static storage duration. -\rSec2[basic.stc.thread]{Thread storage duration} +\rSec3[basic.stc.thread]{Thread storage duration} \pnum \indextext{storage duration!thread}% @@ -2921,7 +3145,7 @@ A variable with thread storage duration shall be initialized before its first odr-use\iref{basic.def.odr} and, if constructed, shall be destroyed on thread exit. -\rSec2[basic.stc.auto]{Automatic storage duration} +\rSec3[basic.stc.auto]{Automatic storage duration} \pnum \indextext{storage duration!automatic}% @@ -2943,7 +3167,7 @@ unused, except that a class object or its copy/move may be eliminated as specified in~\ref{class.copy}. -\rSec2[basic.stc.dynamic]{Dynamic storage duration}% +\rSec3[basic.stc.dynamic]{Dynamic storage duration}% \indextext{storage duration!dynamic|(} \pnum @@ -2952,7 +3176,7 @@ \indextext{\idxcode{new}}% \grammarterm{new-expression}{s}\iref{expr.new}, and destroyed using \indextext{\idxcode{delete}}% -\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp implementation +\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp{} implementation provides access to, and management of, dynamic storage via the global \defn{allocation functions} \tcode{operator new} and \tcode{operator new[]} and the global \defn{deallocation functions} \tcode{operator @@ -2965,7 +3189,7 @@ \pnum The library provides default definitions for the global allocation and deallocation functions. Some global allocation and deallocation -functions are replaceable\iref{new.delete}. A \Cpp program shall +functions are replaceable\iref{new.delete}. A \Cpp{} program shall provide at most one definition of a replaceable allocation or deallocation function. Any such function definition replaces the default version provided in the library\iref{replacement.functions}. The @@ -2974,16 +3198,16 @@ program. \begin{codeblock} -void* operator new(std::size_t); -void* operator new(std::size_t, std::align_val_t); +[[nodiscard]] void* operator new(std::size_t); +[[nodiscard]] void* operator new(std::size_t, std::align_val_t); void operator delete(void*) noexcept; void operator delete(void*, std::size_t) noexcept; void operator delete(void*, std::align_val_t) noexcept; void operator delete(void*, std::size_t, std::align_val_t) noexcept; -void* operator new[](std::size_t); -void* operator new[](std::size_t, std::align_val_t); +[[nodiscard]] void* operator new[](std::size_t); +[[nodiscard]] void* operator new[](std::size_t, std::align_val_t); void operator delete[](void*) noexcept; void operator delete[](void*, std::size_t) noexcept; @@ -3011,12 +3235,12 @@ class\iref{class.free}. \pnum -Any allocation and/or deallocation functions defined in a \Cpp program, +Any allocation and/or deallocation functions defined in a \Cpp{} program, including the default versions in the library, shall conform to the semantics specified in~\ref{basic.stc.dynamic.allocation} and~\ref{basic.stc.dynamic.deallocation}. -\rSec3[basic.stc.dynamic.allocation]{Allocation functions} +\rSec4[basic.stc.dynamic.allocation]{Allocation functions} \pnum \indextext{function!allocation}% @@ -3059,7 +3283,7 @@ returned as a request for zero size is undefined.\footnote{The intent is to have \tcode{operator new()} implementable by calling \tcode{std::malloc()} or \tcode{std::calloc()}, so the rules are -substantially the same. \Cpp differs from C in requiring a zero request +substantially the same. \Cpp{} differs from C in requiring a zero request to return a non-null pointer.} \pnum @@ -3082,7 +3306,7 @@ A global allocation function is only called as the result of a new expression\iref{expr.new}, or called directly using the function call syntax\iref{expr.call}, or called indirectly through calls to the -functions in the \Cpp standard library. \begin{note} In particular, a +functions in the \Cpp{} standard library. \begin{note} In particular, a global allocation function is not called to allocate storage for objects with static storage duration\iref{basic.stc.static}, for objects or references with thread storage duration\iref{basic.stc.thread}, for objects of @@ -3090,7 +3314,7 @@ exception object\iref{except.throw}. \end{note} -\rSec3[basic.stc.dynamic.deallocation]{Deallocation functions} +\rSec4[basic.stc.dynamic.deallocation]{Deallocation functions} \pnum \indextext{function!deallocation}% @@ -3145,7 +3369,7 @@ deallocation function shall deallocate the storage referenced by the pointer, ending the duration of the region of storage. -\rSec3[basic.stc.dynamic.safety]{Safely-derived pointers} +\rSec4[basic.stc.dynamic.safety]{Safely-derived pointers} \pnum \indextext{pointer!safely-derived|(}% @@ -3165,12 +3389,12 @@ A pointer value is a \defn{safely-derived pointer} to a dynamic object only if it has an object pointer type and it is one of the following: \begin{itemize} -\item the value returned by a call to the \Cpp standard library implementation of +\item the value returned by a call to the \Cpp{} standard library implementation of \tcode{::operator new(std::\brk{}size_t)} or \tcode{::operator new(std::size_t, std::align_val_t)}% -;\footnote{This section does not impose restrictions +;\footnote{This subclause does not impose restrictions on indirection through pointers to memory not allocated by \tcode{::operator new}. This -maintains the ability of many \Cpp implementations to use binary libraries and +maintains the ability of many \Cpp{} implementations to use binary libraries and components written in other languages. In particular, this applies to C binaries, because indirection through pointers to memory allocated by \tcode{std::malloc} is not restricted.} @@ -3235,7 +3459,7 @@ \indextext{pointer!safely-derived|)}% \indextext{storage duration!dynamic|)} -\rSec2[basic.stc.inherit]{Duration of subobjects} +\rSec3[basic.stc.inherit]{Duration of subobjects} \pnum \indextext{storage duration!class member}% @@ -3243,264 +3467,93 @@ is that of their complete object\iref{intro.object}. \indextext{storage duration|)}% -\rSec1[basic.life]{Object lifetime} +\rSec2[basic.align]{Alignment} \pnum -\indextext{object lifetime|(}% -The \defn{lifetime} of an object or reference is a runtime property of the -object or reference. -An object is said to have \defnx{non-vacuous initialization}{initialization!non-vacuous} if it is of a class or -aggregate type and it or one of its subobjects is initialized by a constructor -other than a trivial default constructor. \begin{note} Initialization by a -trivial copy/move constructor is non-vacuous initialization. \end{note} -The lifetime of an object of type \tcode{T} begins when: -\begin{itemize} -\item storage with the proper alignment and size for type \tcode{T} is -obtained, and -\item if the object has non-vacuous initialization, its initialization is complete, -\end{itemize} -except that if the object is a union member or subobject thereof, -its lifetime only begins if that union member is the -initialized member in the union~(\ref{dcl.init.aggr}, \ref{class.base.init}), -or as described in \ref{class.union}. -The lifetime of an object \placeholder{o} of type \tcode{T} ends when: -\begin{itemize} -\item if \tcode{T} is a class type with a non-trivial -destructor\iref{class.dtor}, the destructor call starts, or -\item the storage which the object occupies is released, -or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. -\end{itemize} +Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}~(\ref{basic.fundamental}, \ref{basic.compound}) +which place restrictions on the addresses at which an object of that type +may be allocated. An \defn{alignment} is an \impldef{alignment} +integer value representing the number of bytes between successive addresses +at which a given object can be allocated. An object type imposes an alignment +requirement on every object of that type; stricter alignment can be requested +using the alignment specifier\iref{dcl.align}. \pnum -The lifetime of a reference begins when its initialization is complete. -The lifetime of a reference ends as if it were a scalar object. +\indextext{alignment!fundamental}% +A \defn{fundamental alignment} is represented by an alignment +less than or equal to the greatest alignment supported by the implementation in +all contexts, which is equal to +\tcode{alignof(std::max_align_t)}\iref{support.types}. +The alignment required for a type might be different when it is used as the type +of a complete object and when it is used as the type of a subobject. \begin{example} +\begin{codeblock} +struct B { long double d; }; +struct D : virtual B { char c; }; +\end{codeblock} -\pnum -\begin{note} \ref{class.base.init} -describes the lifetime of base and member subobjects. \end{note} +When \tcode{D} is the type of a complete object, it will have a subobject of +type \tcode{B}, so it must be aligned appropriately for a \tcode{long double}. +If \tcode{D} appears as a subobject of another object that also has \tcode{B} +as a virtual base class, the \tcode{B} subobject might be part of a different +subobject, reducing the alignment requirements on the \tcode{D} subobject. +\end{example} The result of the \tcode{alignof} operator reflects the alignment +requirement of the type in the complete-object case. \pnum -The properties ascribed to objects and references throughout this document -apply for a given object or reference only during its lifetime. \begin{note} -In particular, before the lifetime of an object starts and after its -lifetime ends there are significant restrictions on the use of the -object, as described below, in~\ref{class.base.init} and -in~\ref{class.cdtor}. Also, the behavior of an object under construction -and destruction might not be the same as the behavior of an object whose -lifetime has started and not ended. \ref{class.base.init} -and~\ref{class.cdtor} describe the behavior of objects during the -construction and destruction phases. \end{note} +\indextext{alignment!extended}% +\indextext{alignment!new-extended}% +\indextext{over-aligned type|see{type, over-aligned}}% +An \defn{extended alignment} is represented by an alignment +greater than \tcode{alignof(std::max_align_t)}. It is \impldef{support for extended alignments} +whether any extended alignments are supported and the contexts in which they are +supported\iref{dcl.align}. A type having an extended alignment +requirement is an \defnx{over-aligned type}{type!over-aligned}. \begin{note} +Every over-aligned type is or contains a class type +to which extended alignment applies (possibly through a non-static data member). +\end{note} +A \defn{new-extended alignment} is represented by +an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. \pnum -A program may end the lifetime of any object by reusing the storage -which the object occupies or by explicitly calling the destructor for an -object of a class type with a non-trivial destructor. For an object of a -class type with a non-trivial destructor, the program is not required to -call the destructor explicitly before the storage which the object -occupies is reused or released; however, if there is no explicit call to -the destructor or if a \grammarterm{delete-expression}\iref{expr.delete} -is not used to release the storage, the destructor shall not be -implicitly called and any program that depends on the side effects -produced by the destructor has undefined behavior. +Alignments are represented as values of the type \tcode{std::size_t}. +Valid alignments include only those values returned by an \tcode{alignof} +expression for the fundamental types plus an additional \impldef{alignment additional +values} +set of values, which may be empty. +Every alignment value shall be a non-negative integral power of two. \pnum -Before the lifetime of an object has started but after the storage which -the object will occupy has been allocated\footnote{For example, before the -construction of a global object of -non-POD class type\iref{class.cdtor}.} -or, after the lifetime of an object has ended and before the storage -which the object occupied is reused or released, any pointer that represents the address of -the storage location where the object will be or was located may be -used but only in limited ways. -For an object under construction or destruction, see~\ref{class.cdtor}. -Otherwise, such -a pointer refers to allocated -storage\iref{basic.stc.dynamic.deallocation}, and using the pointer as -if the pointer were of type \tcode{void*}, is -well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in -limited ways, as described below. The -program has undefined behavior if: -\begin{itemize} -\item - the object will be or was of a class type with a non-trivial destructor - and the pointer is used as the operand of a \grammarterm{delete-expression}, -\item - the pointer is used to access a non-static data member or call a - non-static member function of the object, or -\item - the pointer is implicitly converted\iref{conv.ptr} to a pointer - to a virtual base class, or -\item - the pointer is used as the operand of a - \tcode{static_cast}\iref{expr.static.cast}, except when the conversion - is to pointer to \cv{}~\tcode{void}, or to pointer to \cv{}~\tcode{void} - and subsequently to pointer to - \cv{}~\tcode{char}, - \cv{}~\tcode{unsigned char}, or - \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or -\item - the pointer is used as the operand of a - \tcode{dynamic_cast}\iref{expr.dynamic.cast}. -\end{itemize} -\begin{example} -\begin{codeblock} -#include - -struct B { - virtual void f(); - void mutate(); - virtual ~B(); -}; - -struct D1 : B { void f(); }; -struct D2 : B { void f(); }; - -void B::mutate() { - new (this) D2; // reuses storage --- ends the lifetime of \tcode{*this} - f(); // undefined behavior - ... = this; // OK, \tcode{this} points to valid memory -} - -void g() { - void* p = std::malloc(sizeof(D1) + sizeof(D2)); - B* pb = new (p) D1; - pb->mutate(); - *pb; // OK: \tcode{pb} points to valid memory - void* q = pb; // OK: \tcode{pb} points to valid memory - pb->f(); // undefined behavior, lifetime of \tcode{*pb} has ended -} -\end{codeblock} -\end{example} +Alignments have an order from \defnx{weaker}{alignment!weaker} to +\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter +alignments have larger alignment values. An address that satisfies an alignment +requirement also satisfies any weaker valid alignment requirement. \pnum -Similarly, before the lifetime of an object has started but after the -storage which the object will occupy has been allocated or, after the -lifetime of an object has ended and before the storage which the object -occupied is reused or released, any glvalue that refers to the original -object may be used but only in limited ways. -For an object under construction or destruction, see~\ref{class.cdtor}. -Otherwise, such -a glvalue refers to -allocated storage\iref{basic.stc.dynamic.deallocation}, and using the -properties of the glvalue that do not depend on its value is -well-defined. The program has undefined behavior if: -\begin{itemize} -\item the glvalue is used to access the object, or -\item the glvalue is used to call a non-static member function of the object, or -\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or -\item the glvalue is used as the operand of a -\tcode{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of -\tcode{typeid}. -\end{itemize} +The alignment requirement of a complete type can be queried using an +\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 +underlying type for an aligned memory area\iref{dcl.align}.\end{note} \pnum -If, after the lifetime of an object has ended and before the storage -which the object occupied is reused or released, a new object is created -at the storage location which the original object occupied, a pointer -that pointed to the original object, a reference that referred to the -original object, or the name of the original object will automatically -refer to the new object and, once the lifetime of the new object has -started, can be used to manipulate the new object, if: -\begin{itemize} -\item the storage for the new object exactly overlays the storage -location which the original object occupied, and - -\item the new object is of the same type as the original object -(ignoring the top-level cv-qualifiers), and - -\item the type of the original object is not const-qualified, and, if a -class type, does not contain any non-static data member whose type is -const-qualified or a reference type, and +Comparing alignments is meaningful and provides the obvious results: -\item the original object was a most derived object\iref{intro.object} -of type \tcode{T} and the new object is a most derived object of type -\tcode{T} (that is, they are not base class subobjects). +\begin{itemize} +\item Two alignments are equal when their numeric values are equal. +\item Two alignments are different when their numeric values are not equal. +\item When an alignment is larger than another it represents a stricter alignment. \end{itemize} -\begin{example} -\begin{codeblock} -struct C { - int i; - void f(); - const C& operator=( const C& ); -}; - -const C& C::operator=( const C& other) { - if ( this != &other ) { - this->~C(); // lifetime of \tcode{*this} ends - new (this) C(other); // new object of type \tcode{C} created - f(); // well-defined - } - return *this; -} - -C c1; -C c2; -c1 = c2; // well-defined -c1.f(); // well-defined; \tcode{c1} refers to a new object of type \tcode{C} -\end{codeblock} -\end{example} -\begin{note} -If these conditions are not met, -a pointer to the new object can be obtained from -a pointer that represents the address of its storage -by calling \tcode{std::launder}\iref{support.dynamic}. -\end{note} - -\pnum -If a program ends the lifetime of an object of type \tcode{T} with -static\iref{basic.stc.static}, thread\iref{basic.stc.thread}, -or automatic\iref{basic.stc.auto} -storage duration and if \tcode{T} has a non-trivial destructor,\footnote{That -is, an object for which a destructor will be called -implicitly---upon exit from the block for an object with -automatic storage duration, upon exit from the thread for an object with -thread storage duration, or upon exit from the program for an object -with static storage duration.} -the program must ensure that an object of the original type occupies -that same storage location when the implicit destructor call takes -place; otherwise the behavior of the program is undefined. This is true -even if the block is exited with an exception. \begin{example} - -\begin{codeblock} -class T { }; -struct B { - ~B(); -}; - -void h() { - B b; - new (&b) T; -} // undefined behavior at block exit -\end{codeblock} -\end{example} \pnum -Creating a new object within the storage that a \tcode{const} complete -object with static, thread, or automatic storage duration occupies, -or within the storage that such a \tcode{const} object used to occupy before -its lifetime ended, results in undefined behavior. -\begin{example} -\begin{codeblock} -struct B { - B(); - ~B(); -}; - -const B b; - -void h() { - b.~B(); - new (const_cast(&b)) const B; // undefined behavior -} -\end{codeblock} -\end{example} +\begin{note} The runtime pointer alignment function\iref{ptr.align} +can be used to obtain an aligned pointer within a buffer; the aligned-storage templates +in the library\iref{meta.trans.other} can be used to obtain aligned storage. +\end{note} \pnum -In this section, ``before'' and ``after'' refer to the ``happens before'' -relation\iref{intro.multithread}. \begin{note} Therefore, undefined behavior results -if an object that is being constructed in one thread is referenced from another -thread without adequate synchronization. \end{note}% -\indextext{object lifetime|)} +If a request for a specific extended alignment in a specific context is not +supported by an implementation, the program is ill-formed. \rSec1[basic.types]{Types}% \indextext{type|(} @@ -3578,7 +3631,7 @@ a set of bits in the object representation that determines a \defn{value}, which is one discrete element of an \impldef{values of a trivially copyable type} set of values.\footnote{The -intent is that the memory model of \Cpp is compatible +intent is that the memory model of \Cpp{} is compatible with that of ISO/IEC 9899 Programming Language C.} \pnum @@ -3647,16 +3700,12 @@ \pnum Arithmetic types\iref{basic.fundamental}, enumeration types, pointer -types, pointer to member types\iref{basic.compound}, +types, pointer-to-member types\iref{basic.compound}, \tcode{std::nullptr_t}, and cv-qualified\iref{basic.type.qualifier} versions of these types are collectively called -\defnx{scalar types}{scalar type}. Scalar types, -POD classes\iref{class}, arrays of such types and -cv-qualified versions of these -types are collectively called -\defnx{POD types}{type!POD}. +\defnx{scalar types}{scalar type}. Cv-unqualified scalar types, trivially copyable class types\iref{class}, arrays of such types, and cv-qualified versions of these types are collectively called \defn{trivially @@ -3697,7 +3746,7 @@ within a constant expression. It is not a guarantee that it is possible to create such an object, nor is it a guarantee that any object of that type -will usable in a constant expression. +will be usable in a constant expression. \end{note} \pnum @@ -3824,7 +3873,7 @@ 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, section 5.2.4.2.1. +the constraints given in the C standard, subclause 5.2.4.2.1. \pnum \indextext{arithmetic!\idxcode{unsigned}}% @@ -3937,7 +3986,7 @@ \pnum A value of type \tcode{std::nullptr_t} is a null pointer constant\iref{conv.ptr}. Such values participate in the pointer and the -pointer to member conversions~(\ref{conv.ptr}, \ref{conv.mem}). +pointer-to-member conversions~(\ref{conv.ptr}, \ref{conv.mem}). \tcode{sizeof(std::nullptr_t)} shall be equal to \tcode{sizeof(void*)}. \pnum @@ -3991,6 +4040,8 @@ ordinary pointers to objects or functions.} which identify members of a given type within objects of a given class, \ref{dcl.mptr}. +Pointers to data members and pointers to member functions are collectively +called \term{pointer-to-member} types. \end{itemize} \pnum @@ -4208,222 +4259,1291 @@ \end{example}% \indextext{type|)} -\rSec1[basic.lval]{Lvalues and rvalues} +\rSec2[conv.rank]{Integer conversion rank}% +\indextext{conversion!integer rank} + \pnum -Expressions are categorized according to the taxonomy in Figure~\ref{fig:categories}. +Every integer type has an \term{integer conversion rank} defined as follows: + +\begin{itemize} +\item No two signed integer types other than \tcode{char} and \tcode{signed +char} (if \tcode{char} is signed) shall have the same rank, even if they have +the same representation. + +\item The rank of a signed integer type shall be greater than the rank +of any signed integer type with a smaller size. + +\item The rank of \tcode{long long int} shall be greater +than the rank of \tcode{long int}, which shall be greater than +the rank of \tcode{int}, which shall be greater than the rank of +\tcode{short int}, which shall be greater than the rank of +\tcode{signed char}. + +\item The rank of any unsigned integer type shall equal the rank of the +corresponding signed integer type. + +\item The rank of any standard integer type shall be greater than the +rank of any extended integer type with the same size. + +\item The rank of \tcode{char} shall equal the rank of \tcode{signed char} +and \tcode{unsigned char}. -\begin{importgraphic} -{Expression category taxonomy} -{fig:categories} -{valuecategories.pdf} -\end{importgraphic} +\item The rank of \tcode{bool} shall be less than the rank of all other +standard integer types. +\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 +\tcode{wchar_t} shall equal the ranks of their underlying +types\iref{basic.fundamental}. + +\item The rank of any extended signed integer type relative to another +extended signed integer type with the same size is \impldef{rank of extended signed +integer type}, but still subject to the other rules for determining the integer +conversion rank. + +\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if +\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater +rank than \tcode{T3}, then \tcode{T1} shall have greater rank than +\tcode{T3}. +\end{itemize} + +\begin{note} +The integer conversion rank is used in the definition of the integral +promotions\iref{conv.prom} and the usual arithmetic +conversions\iref{expr.prop}. +\end{note}% + +\rSec1[basic.exec]{Program execution} + +\rSec2[intro.execution]{Sequential execution} + +\pnum +An instance of each object with automatic storage +duration\iref{basic.stc.auto} is associated with each entry into its +block. Such an object exists and retains its last-stored value during +the execution of the block and while the block is suspended (by a call +of a function or receipt of a signal). + +\pnum +A \defn{constituent expression} is defined as follows: \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, -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 +The constituent expression of an expression is that expression. +\item +The constituent expressions of a \grammarterm{braced-init-list} or +of a (possibly parenthesized) \grammarterm{expression-list} +are the constituent expressions of the elements of the respective list. +\item +The constituent expressions of a \grammarterm{brace-or-equal-initializer} +of the form \tcode{=}~\grammarterm{initializer-clause} +are the constituent expressions of the \grammarterm{initializer-clause}. +\end{itemize} \begin{example} -Certain kinds of expressions involving rvalue references\iref{dcl.ref} yield xvalues, -such as a call to a function whose return type is an rvalue reference -or a cast to an rvalue reference type. +\begin{codeblock} +struct A { int x; }; +struct B { int y; struct A a; }; +B b = { 5, { 1+1 } }; +\end{codeblock} +The constituent expressions of the \grammarterm{initializer} +used for the initialization of \tcode{b} are \tcode{5} and \tcode{1+1}. \end{example} -\item An \defn{lvalue} is a glvalue that is not an xvalue. -\item An \defn{rvalue} is a prvalue or an xvalue. + +\pnum +The \defnx{immediate subexpressions}{immediate subexpression} of an expression \tcode{e} are +\begin{itemize} +\item +the constituent expressions of \tcode{e}'s operands\iref{expr.prop}, +\item +any function call that \tcode{e} implicitly invokes, +\item +if \tcode{e} is a \grammarterm{lambda-expression}\iref{expr.prim.lambda}, +the initialization of the entities captured by copy and +the constituent expressions of the \grammarterm{initializer} of the \grammarterm{init-capture}{s}, +\item +if \tcode{e} is a function call\iref{expr.call} or implicitly invokes a function, +the constituent expressions of each default argument\iref{dcl.fct.default} +used in the call, or +\item +if \tcode{e} creates an aggregate object\iref{dcl.init.aggr}, +the constituent expressions of each default member initializer\iref{class.mem} +used in the initialization. +\end{itemize} + +\pnum +A \defn{subexpression} of an expression \tcode{e} is +an immediate subexpression of \tcode{e} or +a subexpression of an immediate subexpression of \tcode{e}. +\begin{note} +Expressions appearing in the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +are not subexpressions of the \grammarterm{lambda-expression}. +\end{note} + +\pnum +A \defn{full-expression} is +\begin{itemize} +\item +an unevaluated operand\iref{expr.prop}, +\item +a \grammarterm{constant-expression}\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, +\item +an invocation of a destructor generated at the end of the lifetime +of an object other than a temporary object\iref{class.temporary}, or +\item +an expression that is not a subexpression of another expression and +that is not otherwise part of a full-expression. +\end{itemize} +If a language construct is defined to produce an implicit call of a function, +a use of the language construct is considered to be an expression +for the purposes of this definition. +Conversions applied to the result of an expression in order to satisfy the requirements +of the language construct in which the expression appears +are also considered to be part of the full-expression. +For an initializer, performing the initialization of the entity +(including evaluating default member initializers of an aggregate) +is also considered part of the full-expression. +\begin{example} +\begin{codeblock} +struct S { + S(int i): I(i) { } // full-expression is initialization of \tcode{I} + int& v() { return I; } + ~S() noexcept(false) { } +private: + int I; +}; + +S s1(1); // full-expression comprises call of \tcode{S::S(int)} +void f() { + S s2 = 2; // full-expression comprises call of \tcode{S::S(int)} + if (S(3).v()) // full-expression includes lvalue-to-rvalue and \tcode{int} to \tcode{bool} conversions, + // performed before temporary is deleted at end of full-expression + { } + bool b = noexcept(S()); // exception specification of destructor of \tcode{S} considered for \tcode{noexcept} + + // full-expression is destruction of \tcode{s2} at end of block +} +struct B { + B(S = S(0)); +}; +B b[2] = { B(), B() }; // full-expression is the entire initialization + // including the destruction of temporaries +\end{codeblock} +\end{example} + +\pnum +\begin{note} The evaluation of a full-expression can include the +evaluation of subexpressions that are not lexically part of the +full-expression. For example, subexpressions involved in evaluating +default arguments\iref{dcl.fct.default} are considered to +be created in the expression that calls the function, not the expression +that defines the default argument. \end{note} + +\pnum +\indextext{value computation|(}% +Reading an object designated by a \tcode{volatile} +glvalue\iref{basic.lval}, modifying an object, calling a library I/O +function, or calling a function that does any of those operations are +all +\defn{side effects}, which are changes in the state of the execution +environment. \defnx{Evaluation}{evaluation} of an expression (or a +subexpression) in general includes both value computations (including +determining the identity of an object for glvalue evaluation and fetching +a value previously assigned to an object for prvalue evaluation) and +initiation of side effects. When a call to a library I/O function +returns or an access through a volatile glvalue is evaluated the side +effect is considered complete, even though some external actions implied +by the call (such as the I/O itself) or by the \tcode{volatile} access +may not have completed yet. + +\pnum +\defnx{Sequenced before}{sequenced before} is an asymmetric, transitive, pair-wise relation between +evaluations executed by a single thread\iref{intro.multithread}, which induces +a partial order among those evaluations. Given any two evaluations \placeholder{A} and +\placeholder{B}, if \placeholder{A} is sequenced before \placeholder{B} +(or, equivalently, \placeholder{B} is \defn{sequenced after} \placeholder{A}), +then the execution of +\placeholder{A} shall precede the execution of \placeholder{B}. If \placeholder{A} is not sequenced +before \placeholder{B} and \placeholder{B} is not sequenced before \placeholder{A}, then \placeholder{A} and +\placeholder{B} are \defn{unsequenced}. \begin{note} The execution of unsequenced +evaluations can overlap. \end{note} Evaluations \placeholder{A} and \placeholder{B} are +\defn{indeterminately sequenced} when either \placeholder{A} is sequenced before +\placeholder{B} or \placeholder{B} is sequenced before \placeholder{A}, but it is unspecified which. +\begin{note} Indeterminately sequenced evaluations cannot overlap, but either +could be executed first. \end{note} +An expression \placeholder{X} +is said to be sequenced before +an expression \placeholder{Y} if +every value computation and every side effect +associated with the expression \placeholder{X} +is sequenced before +every value computation and every side effect +associated with the expression \placeholder{Y}. + +\pnum +Every +\indextext{value computation}% +value computation and +\indextext{side effects}% +side effect associated with a full-expression is +sequenced before every value computation and side effect associated with the +next full-expression to be evaluated.\footnote{As specified +in~\ref{class.temporary}, after a full-expression is evaluated, a sequence of +zero or more invocations of destructor functions for temporary objects takes +place, usually in reverse order of the construction of each temporary object.} + +\pnum +\indextext{evaluation!unspecified order of}% +Except where noted, evaluations of operands of individual operators and +of subexpressions of individual expressions are unsequenced. \begin{note} +In an expression that is evaluated more than once during the execution +of a program, unsequenced and indeterminately sequenced evaluations of +its subexpressions need not be performed consistently in different +evaluations. \end{note} The value computations of the operands of an +operator are sequenced before the value computation of the result of the +operator. If a +\indextext{side effects}% +side effect on a memory location\iref{intro.memory} is unsequenced +relative to either another side effect on the same memory location or +a value computation using the value of any object in the same memory location, +and they are not potentially concurrent\iref{intro.multithread}, +the behavior is undefined. +\begin{note} +The next subclause imposes similar, but more complex restrictions on +potentially concurrent computations. +\end{note} + +\begin{example} + +\begin{codeblock} +void g(int i) { + i = 7, i++, i++; // \tcode{i} becomes \tcode{9} + + i = i++ + 1; // the value of \tcode{i} is incremented + i = i++ + i; // the behavior is undefined + i = i + 1; // the value of \tcode{i} is incremented +} +\end{codeblock} +\end{example} + +\pnum +When calling a function (whether or not the function is inline), every +\indextext{value computation}% +value computation and +\indextext{side effects}% +side effect associated with any argument +expression, or with the postfix expression designating the called +function, is sequenced before execution of every expression or statement +in the body of the called function. +For each function invocation \placeholder{F}, +for every evaluation \placeholder{A} that occurs within \placeholder{F} and +every evaluation \placeholder{B} that does not occur within \placeholder{F} but +is evaluated on the same thread and as part of the same signal handler (if any), +either \placeholder{A} is sequenced before \placeholder{B} or +\placeholder{B} is sequenced before \placeholder{A}.\footnote{In other words, +function executions do not interleave with each other.} +\begin{note} +If \placeholder{A} and \placeholder{B} would not otherwise be sequenced then they are +indeterminately sequenced. +\end{note} +Several contexts in \Cpp{} cause evaluation of a function call, even +though no corresponding function call syntax appears in the translation +unit. +\begin{example} +Evaluation of a \grammarterm{new-expression} invokes one or more allocation +and constructor functions; see~\ref{expr.new}. For another example, +invocation of a conversion function\iref{class.conv.fct} can arise in +contexts in which no function call syntax appears. +\end{example} +The sequencing constraints on the execution of the called function (as +described above) are features of the function calls as evaluated, +whatever the syntax of the expression that calls the function might be.% +\indextext{value computation|)}% + +\indextext{behavior!on receipt of signal}% +\indextext{signal}% +\pnum +If a signal handler is executed as a result of a call to the \tcode{std::raise} +function, then the execution of the handler is sequenced after the invocation +of the \tcode{std::raise} function and before its return. +\begin{note} When a signal is received for another reason, the execution of the +signal handler is usually unsequenced with respect to the rest of the program. +\end{note} +\indextext{program execution|)} + +\rSec2[intro.multithread]{Multi-threaded executions and data races} + +\pnum +\indextext{threads!multiple|(}% +\indextext{operation!atomic|(}% +A \defn{thread of execution} (also known as a \defn{thread}) is a single flow of +control within a program, including the initial invocation of a specific +top-level function, and recursively including every function invocation +subsequently executed by the thread. \begin{note} When one thread creates another, +the initial call to the top-level function of the new thread is executed by the +new thread, not by the creating thread. \end{note} Every thread in a program can +potentially access every object and function in a program.\footnote{An object +with automatic or thread storage duration\iref{basic.stc} is associated with +one specific thread, and can be accessed by a different thread only indirectly +through a pointer or reference\iref{basic.compound}.} Under a hosted +implementation, a \Cpp{} program can have more than one thread running +concurrently. The execution of each thread proceeds as defined by the remainder +of this document. The execution of the entire program consists of an execution +of all of its threads. \begin{note} Usually the execution can be viewed as an +interleaving of all its threads. However, some kinds of atomic operations, for +example, allow executions inconsistent with a simple interleaving, as described +below. \end{note} Under a freestanding implementation, it is \impldef{number of +threads in a program under a freestanding implementation} whether a program can +have more than one thread of execution. + +\pnum +For a signal handler that is not executed as a result of a call to the +\tcode{std::raise} function, it is unspecified which thread of execution +contains the signal handler invocation. + +\rSec3[intro.races]{Data races} + +\pnum +The value of an object visible to a thread \placeholder{T} at a particular point is the +initial value of the object, a value assigned to the object by \placeholder{T}, or a +value assigned to the object by another thread, according to the rules below. +\begin{note} In some cases, there may instead be undefined behavior. Much of this +subclause is motivated by the desire to support atomic operations with explicit +and detailed visibility constraints. However, it also implicitly supports a +simpler view for more restricted programs. \end{note} + +\pnum +Two expression evaluations \defn{conflict} if one of them modifies a memory +location\iref{intro.memory} and the other one reads or modifies the same +memory location. + +\pnum +The library defines a number of atomic operations\iref{atomics} and +operations on mutexes\iref{thread} that are specially identified as +synchronization operations. These operations play a special role in making +assignments in one thread visible to another. A synchronization operation on one +or more memory locations is either a consume operation, an acquire operation, a +release operation, or both an acquire and release operation. A synchronization +operation without an associated memory location is a fence and can be either an +acquire fence, a release fence, or both an acquire and release fence. In +addition, there are relaxed atomic operations, which are not synchronization +operations, and atomic read-modify-write operations, which have special +characteristics. \begin{note} For example, a call that acquires a mutex will +perform an acquire operation on the locations comprising the mutex. +Correspondingly, a call that releases the same mutex will perform a release +operation on those same locations. Informally, performing a release operation on +\placeholder{A} forces prior +\indextext{side effects}% +side effects on other memory locations to become visible +to other threads that later perform a consume or an acquire operation on +\placeholder{A}. ``Relaxed'' atomic operations are not synchronization operations even +though, like synchronization operations, they cannot contribute to data races. +\end{note} + +\pnum +All modifications to a particular atomic object \placeholder{M} occur in some +particular total order, called the \defn{modification order} of \placeholder{M}. +\begin{note} There is a separate order for each +atomic object. There is no requirement that these can be combined into a single +total order for all objects. In general this will be impossible since different +threads may observe modifications to different objects in inconsistent orders. +\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 +\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} + +\pnum +Certain library calls \defn{synchronize with} other library calls performed by +another thread. For example, an atomic store-release synchronizes with a +load-acquire that takes its value from the store\iref{atomics.order}. +\begin{note} Except in the specified cases, reading a later value does not +necessarily ensure visibility as described below. Such a requirement would +sometimes interfere with efficient implementation. \end{note} \begin{note} The +specifications of the synchronization operations define when one reads the value +written by another. For atomic objects, the definition is clear. All operations +on a given mutex occur in a single total order. Each mutex acquisition ``reads +the value written'' by the last mutex release. \end{note} + +\pnum +An evaluation \placeholder{A} \defn{carries a dependency} to an evaluation \placeholder{B} if + +\begin{itemize} +\item +the value of \placeholder{A} is used as an operand of \placeholder{B}, unless: +\begin{itemize} +\item +\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}) +operator, or +\item +\placeholder{A} is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) +operator, or +\item +\placeholder{A} is the left operand of the built-in comma (\tcode{,}) +operator\iref{expr.comma}; \end{itemize} or +\item +\placeholder{A} writes a scalar object or bit-field \placeholder{M}, \placeholder{B} reads the value +written by \placeholder{A} from \placeholder{M}, and \placeholder{A} is sequenced before \placeholder{B}, or +\item +for some evaluation \placeholder{X}, \placeholder{A} carries a dependency to \placeholder{X}, and +\placeholder{X} carries a dependency to \placeholder{B}. +\end{itemize} +\begin{note} ``Carries a dependency to'' is a subset of ``is sequenced before'', +and is similarly strictly intra-thread. \end{note} + +\pnum +An evaluation \placeholder{A} is \defn{dependency-ordered before} an evaluation +\placeholder{B} if +\begin{itemize} +\item +\placeholder{A} performs a release operation on an atomic object \placeholder{M}, and, in +another thread, \placeholder{B} performs a consume operation on \placeholder{M} and reads a +value written by any +\indextext{side effects}% +side effect in the release sequence headed by \placeholder{A}, or + +\item +for some evaluation \placeholder{X}, \placeholder{A} is dependency-ordered before \placeholder{X} and +\placeholder{X} carries a dependency to \placeholder{B}. + +\end{itemize} +\begin{note} The relation ``is dependency-ordered before'' is analogous to +``synchronizes with'', but uses release/consume in place of release/acquire. +\end{note} + +\pnum +An evaluation \placeholder{A} \defn{inter-thread happens before} an evaluation \placeholder{B} +if +\begin{itemize} +\item + \placeholder{A} synchronizes with \placeholder{B}, or +\item + \placeholder{A} is dependency-ordered before \placeholder{B}, or +\item + for some evaluation \placeholder{X} + \begin{itemize} + \item + \placeholder{A} synchronizes with \placeholder{X} and \placeholder{X} + is sequenced before \placeholder{B}, or + \item + \placeholder{A} is sequenced before \placeholder{X} and \placeholder{X} + inter-thread happens before \placeholder{B}, or + \item + \placeholder{A} inter-thread happens before \placeholder{X} and \placeholder{X} + inter-thread happens before \placeholder{B}. + \end{itemize} +\end{itemize} +\begin{note} The ``inter-thread happens before'' relation describes arbitrary +concatenations of ``sequenced before'', ``synchronizes with'' and +``dependency-ordered before'' relationships, with two exceptions. The first +exception is that a concatenation is not permitted to end with +``dependency-ordered before'' followed by ``sequenced before''. The reason for +this limitation is that a consume operation participating in a +``dependency-ordered before'' relationship provides ordering only with respect +to operations to which this consume operation actually carries a dependency. The +reason that this limitation applies only to the end of such a concatenation is +that any subsequent release operation will provide the required ordering for a +prior consume operation. The second exception is that a concatenation is not +permitted to consist entirely of ``sequenced before''. The reasons for this +limitation are (1) to permit ``inter-thread happens before'' to be transitively +closed and (2) the ``happens before'' relation, defined below, provides for +relationships consisting entirely of ``sequenced before''. \end{note} + +\pnum +An evaluation \placeholder{A} \defn{happens before} an evaluation \placeholder{B} +(or, equivalently, \placeholder{B} \defn{happens after} \placeholder{A}) if: +\begin{itemize} +\item \placeholder{A} is sequenced before \placeholder{B}, or +\item \placeholder{A} inter-thread happens before \placeholder{B}. +\end{itemize} +The implementation shall ensure that no program execution demonstrates a cycle +in the ``happens before'' relation. \begin{note} This cycle would otherwise be +possible only through the use of consume operations. \end{note} + +\pnum +An evaluation \placeholder{A} \defn{strongly 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}. +\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. +\end{note} + +\pnum +A \defnx{visible side effect}{side effects!visible} \placeholder{A} on a scalar object or bit-field \placeholder{M} +with respect to a value computation \placeholder{B} of \placeholder{M} satisfies the +conditions: +\begin{itemize} +\item \placeholder{A} happens before \placeholder{B} and +\item there is no other +\indextext{side effects}% +side effect \placeholder{X} to \placeholder{M} such that \placeholder{A} +happens before \placeholder{X} and \placeholder{X} happens before \placeholder{B}. +\end{itemize} + +The value of a non-atomic scalar object or bit-field \placeholder{M}, as determined by +evaluation \placeholder{B}, shall be the value stored by the +\indextext{side effects!visible}% +visible side effect +\placeholder{A}. \begin{note} If there is ambiguity about which side effect to a +non-atomic object or bit-field is visible, then the behavior is either +unspecified or undefined. \end{note} \begin{note} This states that operations on +ordinary objects are not visibly reordered. This is not actually detectable +without data races, but it is necessary to ensure that data races, as defined +below, and with suitable restrictions on the use of atomics, correspond to data +races in a simple interleaved (sequentially consistent) execution. \end{note} + +\pnum +The value of an +atomic object \placeholder{M}, as determined by evaluation \placeholder{B}, shall be the value +stored by some +side effect \placeholder{A} that modifies \placeholder{M}, where \placeholder{B} does not happen +before \placeholder{A}. +\begin{note} +The set of such side effects is also restricted by the rest of the rules +described here, and in particular, by the coherence requirements below. +\end{note} + +\pnum +\indextext{coherence!write-write}% +If an operation \placeholder{A} that modifies an atomic object \placeholder{M} happens before +an operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall be earlier +than \placeholder{B} in the modification order of \placeholder{M}. \begin{note} This requirement +is known as write-write coherence. \end{note} + +\pnum +\indextext{coherence!read-read}% +If a +\indextext{value computation}% +value computation \placeholder{A} of an atomic object \placeholder{M} happens before a +value computation \placeholder{B} of \placeholder{M}, and \placeholder{A} takes its value from a side +effect \placeholder{X} on \placeholder{M}, then the value computed by \placeholder{B} shall either be +the value stored by \placeholder{X} or the value stored by a +\indextext{side effects}% +side effect \placeholder{Y} on +\placeholder{M}, where \placeholder{Y} follows \placeholder{X} in the modification order of \placeholder{M}. +\begin{note} This requirement is known as read-read coherence. \end{note} + +\pnum +\indextext{coherence!read-write}% +If a +\indextext{value computation}% +value computation \placeholder{A} of an atomic object \placeholder{M} happens before an +operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall take its value from a side +effect \placeholder{X} on \placeholder{M}, where \placeholder{X} precedes \placeholder{B} in the +modification order of \placeholder{M}. \begin{note} This requirement is known as +read-write coherence. \end{note} + +\pnum +\indextext{coherence!write-read}% +If a +\indextext{side effects}% +side effect \placeholder{X} on an atomic object \placeholder{M} happens before a value +computation \placeholder{B} of \placeholder{M}, then the evaluation \placeholder{B} shall take its +value from \placeholder{X} or from a +\indextext{side effects}% +side effect \placeholder{Y} that follows \placeholder{X} in the +modification order of \placeholder{M}. \begin{note} This requirement is known as +write-read coherence. \end{note} + +\pnum +\begin{note} The four preceding coherence requirements effectively disallow +compiler reordering of atomic operations to a single object, even if both +operations are relaxed loads. This effectively makes the cache coherence +guarantee provided by most hardware available to \Cpp{} atomic operations. +\end{note} + +\pnum +\begin{note} The value observed by a load of an atomic depends on the ``happens +before'' relation, which depends on the values observed by loads of atomics. +The intended reading is that there must exist an +association of atomic loads with modifications they observe that, together with +suitably chosen modification orders and the ``happens before'' relation derived +as described above, satisfy the resulting constraints as imposed here. \end{note} + +\pnum +Two actions are \defn{potentially concurrent} if +\begin{itemize} +\item they are performed by different threads, or +\item they are unsequenced, at least one is performed by a signal handler, and +they are not both performed by the same signal handler invocation. +\end{itemize} +The execution of a program contains a \defn{data race} if it contains two +potentially concurrent conflicting actions, at least one of which is not atomic, +and neither happens before the other, +except for the special case for signal handlers described below. +Any such data race results in undefined +behavior. \begin{note} It can be shown that programs that correctly use mutexes +and \tcode{memory_order::seq_cst} operations to prevent all data races and use no +other synchronization operations behave as if the operations executed by their +constituent threads were simply interleaved, with each +\indextext{value computation}% +value computation of an +object being taken from the last +\indextext{side effects}% +side effect on that object in that +interleaving. This is normally referred to as ``sequential consistency''. +However, this applies only to data-race-free programs, and data-race-free +programs cannot observe most program transformations that do not change +single-threaded program semantics. In fact, most single-threaded program +transformations continue to be allowed, since any program that behaves +differently as a result must perform an undefined operation. \end{note} + +\pnum +Two accesses to the same object of type \tcode{volatile std::sig_atomic_t} do not +result in a data race if both occur in the same thread, even if one or more +occurs in a signal handler. For each signal handler invocation, evaluations +performed by the thread invoking a signal handler can be divided into two +groups \placeholder{A} and \placeholder{B}, such that no evaluations in +\placeholder{B} happen before evaluations in \placeholder{A}, and the +evaluations of such \tcode{volatile std::sig_atomic_t} objects take values as though +all evaluations in \placeholder{A} happened before the execution of the signal +handler and the execution of the signal handler happened before all evaluations +in \placeholder{B}. + +\pnum +\begin{note} Compiler transformations that introduce assignments to a potentially +shared memory location that would not be modified by the abstract machine are +generally precluded by this document, since such an assignment might overwrite +another assignment by a different thread in cases in which an abstract machine +execution would not have encountered a data race. This includes implementations +of data member assignment that overwrite adjacent members in separate memory +locations. Reordering of atomic loads in cases in which the atomics in question +may alias is also generally precluded, since this may violate the coherence +rules. \end{note} + +\pnum +\begin{note} Transformations that introduce a speculative read of a potentially +shared memory location may not preserve the semantics of the \Cpp{} program as +defined in this document, since they potentially introduce a data race. However, +they are typically valid in the context of an optimizing compiler that targets a +specific machine with well-defined semantics for data races. They would be +invalid for a hypothetical machine that is not tolerant of races or provides +hardware race detection. \end{note} + +\rSec3[intro.progress]{Forward progress} + +\pnum +The implementation may assume that any thread will eventually do one of the +following: +\begin{itemize} +\item terminate, +\item make a call to a library I/O function, +\item perform an access through a volatile glvalue, or +\item perform a synchronization operation or an atomic operation. +\end{itemize} +\begin{note} This is intended to allow compiler transformations such as removal of +empty loops, even when termination cannot be proven. \end{note} + +\pnum +Executions of atomic functions +that are either defined to be lock-free\iref{atomics.flag} +or indicated as lock-free\iref{atomics.lockfree} +are \defnx{lock-free executions}{lock-free execution}. +\begin{itemize} +\item + If there is only one thread that is not blocked\iref{defns.block} + in a standard library function, + a lock-free execution in that thread shall complete. + \begin{note} + Concurrently executing threads + may prevent progress of a lock-free execution. + For example, + this situation can occur + with load-locked store-conditional implementations. + This property is sometimes termed obstruction-free. + \end{note} +\item + When one or more lock-free executions run concurrently, + at least one should complete. + \begin{note} + It is difficult for some implementations + to provide absolute guarantees to this effect, + since repeated and particularly inopportune interference + from other threads + may prevent forward progress, + e.g., + by repeatedly stealing a cache line + for unrelated purposes + between load-locked and store-conditional instructions. + Implementations should ensure + that such effects cannot indefinitely delay progress + under expected operating conditions, + and that such anomalies + can therefore safely be ignored by programmers. + Outside this document, + this property is sometimes termed lock-free. + \end{note} +\end{itemize} + +\pnum +During the execution of a thread of execution, each of the following is termed +an \defn{execution step}: +\begin{itemize} +\item termination of the thread of execution, +\item performing an access through a volatile glvalue, or +\item completion of a call to a library I/O function, a + synchronization operation, or an atomic operation. +\end{itemize} + +\pnum +An invocation of a standard library function that blocks\iref{defns.block} +is considered to continuously execute execution steps while waiting for the +condition that it blocks on to be satisfied. +\begin{example} +A library I/O function that blocks until the I/O operation is complete can +be considered to continuously check whether the operation is complete. Each +such check might consist of one or more execution steps, for example using +observable behavior of the abstract machine. +\end{example} + +\pnum +\begin{note} +Because of this and the preceding requirement regarding what threads of execution +have to perform eventually, it follows that no thread of execution can execute +forever without an execution step occurring. +\end{note} + +\pnum +A thread of execution \defnx{makes progress}{make progress!thread} +when an execution step occurs or a +lock-free execution does not complete because there are other concurrent threads +that are not blocked in a standard library function (see above). + +\pnum +\indextext{forward progress guarantees!concurrent}% +For a thread of execution providing \defn{concurrent forward progress guarantees}, +the implementation ensures that the thread will eventually make progress for as +long as it has not terminated. +\begin{note} +This is required regardless of whether or not other threads of executions (if any) +have been or are making progress. To eventually fulfill this requirement means that +this will happen in an unspecified but finite amount of time. +\end{note} + +\pnum +It is \impldef{whether the thread that executes \tcode{main} and the threads created +by \tcode{std::thread} provide concurrent forward progress guarantees} whether the +implementation-created thread of execution that executes +\tcode{main}\iref{basic.start.main} and the threads of execution created by +\tcode{std::thread}\iref{thread.thread.class} provide concurrent forward progress +guarantees. +\begin{note} +General-purpose implementations should provide these guarantees. +\end{note} + +\pnum +\indextext{forward progress guarantees!parallel}% +For a thread of execution providing \defn{parallel forward progress guarantees}, +the implementation is not required to ensure that the thread will eventually make +progress if it has not yet executed any execution step; once this thread has +executed a step, it provides concurrent forward progress guarantees. + +\pnum +\begin{note} +This does not specify a requirement for when to start this thread of execution, +which will typically be specified by the entity that creates this thread of +execution. For example, a thread of execution that provides concurrent forward +progress guarantees and executes tasks from a set of tasks in an arbitrary order, +one after the other, satisfies the requirements of parallel forward progress for +these tasks. +\end{note} + +\pnum +\indextext{forward progress guarantees!weakly parallel}% +For a thread of execution providing \defn{weakly parallel forward progress +guarantees}, the implementation does not ensure that the thread will eventually +make progress. + +\pnum +\begin{note} +Threads of execution providing weakly parallel forward progress guarantees cannot +be expected to make progress regardless of whether other threads make progress or +not; however, blocking with forward progress guarantee delegation, as defined below, +can be used to ensure that such threads of execution make progress eventually. +\end{note} + +\pnum +Concurrent forward progress guarantees are stronger than parallel forward progress +guarantees, which in turn are stronger than weakly parallel forward progress +guarantees. +\begin{note} +For example, some kinds of synchronization between threads of execution may only +make progress if the respective threads of execution provide parallel forward progress +guarantees, but will fail to make progress under weakly parallel guarantees. +\end{note} + +\pnum +\indextext{forward progress guarantees!delegation of}% +When a thread of execution \placeholder{P} is specified to \defn{block with forward +progress guarantee delegation} on the completion of a set \placeholder{S} of threads +of execution, then throughout the whole time of \placeholder{P} being blocked on +\placeholder{S}, the implementation shall ensure that the forward progress guarantees +provided by at least one thread of execution in \placeholder{S} is at least as strong +as \placeholder{P}'s forward progress guarantees. +\begin{note} +It is unspecified which thread or threads of execution in \placeholder{S} are chosen +and for which number of execution steps. The strengthening is not permanent and +not necessarily in place for the rest of the lifetime of the affected thread of +execution. As long as \placeholder{P} is blocked, the implementation has to eventually +select and potentially strengthen a thread of execution in \placeholder{S}. +\end{note} +Once a thread of execution in \placeholder{S} terminates, it is removed from \placeholder{S}. +Once \placeholder{S} is empty, \placeholder{P} is unblocked. + +\pnum +\begin{note} +A thread of execution \placeholder{B} thus can temporarily provide an effectively +stronger forward progress guarantee for a certain amount of time, due to a +second thread of execution \placeholder{A} being blocked on it with forward +progress guarantee delegation. In turn, if \placeholder{B} then blocks with +forward progress guarantee delegation on \placeholder{C}, this may also temporarily +provide a stronger forward progress guarantee to \placeholder{C}. +\end{note} + +\pnum +\begin{note} +If all threads of execution in \placeholder{S} finish executing (e.g., they terminate +and do not use blocking synchronization incorrectly), then \placeholder{P}'s execution +of the operation that blocks with forward progress guarantee delegation will not +result in \placeholder{P}'s progress guarantee being effectively weakened. +\end{note} + +\pnum +\begin{note} +This does not remove any constraints regarding blocking synchronization for +threads of execution providing parallel or weakly parallel forward progress +guarantees because the implementation is not required to strengthen a particular +thread of execution whose too-weak progress guarantee is preventing overall progress. +\end{note} + +\pnum +An implementation should ensure that the last value (in modification order) +assigned by an atomic or synchronization operation will become visible to all +other threads in a finite period of time.% +\indextext{operation!atomic|)}% +\indextext{threads!multiple|)} + +\rSec2[basic.start]{Start and termination} + +\rSec3[basic.start.main]{\tcode{main} function} +\indextext{\idxcode{main} function|(} + +\pnum +\indextext{program!start|(}% +A program shall contain a global function called \tcode{main}. +Executing a program starts a main thread of execution~(\ref{intro.multithread}, \ref{thread.threads}) +in which the \tcode{main} function is invoked, +and in which variables of static storage duration +might be initialized\iref{basic.start.static} and destroyed\iref{basic.start.term}. +It is \impldef{defining \tcode{main} in freestanding environment} +whether a program in a freestanding environment is required to define a \tcode{main} +function. \begin{note} In a freestanding environment, start-up and termination is +\impldef{start-up and termination in freestanding environment}; start-up contains the +execution of constructors for objects of namespace scope with static storage duration; +termination contains the execution of destructors for objects with static storage +duration. \end{note} + +\pnum +An implementation shall not predefine the \tcode{main} function. This +function shall not be overloaded. Its type shall have \Cpp{} language linkage +and it shall have a declared return type of type +\tcode{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. +\indextext{\idxcode{main} function!implementation-defined parameters to}% +An implementation shall allow both +\begin{itemize} +\item a function of \tcode{()} returning \tcode{int} and +\item a function of \tcode{(int}, pointer to pointer to \tcode{char)} returning \tcode{int} +\end{itemize} + +\indextext{\idxcode{argc}}% +\indextext{\idxcode{argv}}% +as the type of \tcode{main}\iref{dcl.fct}. +\indextext{\idxcode{main} function!parameters to}% +\indextext{environment!program}% +In the latter form, for purposes of exposition, the first function +parameter is called \tcode{argc} and the second function parameter is +called \tcode{argv}, where \tcode{argc} shall be the number of +arguments passed to the program from the environment in which the +program is run. If +\tcode{argc} is nonzero these arguments shall be supplied in +\tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial +characters of null-terminated multibyte strings (\ntmbs{}s)\iref{multibyte.strings} +and \tcode{argv[0]} shall be the pointer to +the initial character of a \ntmbs{} that represents the name used to +invoke the program or \tcode{""}. The value of \tcode{argc} shall be +non-negative. The value of \tcode{argv[argc]} shall be 0. \begin{note} It +is recommended that any further (optional) parameters be added after +\tcode{argv}. \end{note} + +\pnum +The function \tcode{main} shall not be used within +a program. +\indextext{\idxcode{main} function!implementation-defined linkage of}% +The linkage\iref{basic.link} of \tcode{main} is +\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as +deleted or that declares \tcode{main} to be +\tcode{inline}, \tcode{static}, or \tcode{constexpr} is ill-formed. +The \tcode{main} function shall not be declared with a +\grammarterm{linkage-specification}\iref{dcl.link}. A program that +declares a variable \tcode{main} at global scope or that declares the name +\tcode{main} with C language linkage (in any namespace) is ill-formed. +The name \tcode{main} is +not otherwise reserved. \begin{example} Member functions, classes, and +enumerations can be called \tcode{main}, as can entities in other +namespaces. \end{example} + +\pnum +\indextext{\idxcode{exit}}% +\indexlibrary{\idxcode{exit}}% +\indextext{termination!program}% +Terminating the program +without leaving the current block (e.g., by calling the function +\tcode{std::exit(int)}\iref{support.start.term}) does not destroy any +objects with automatic storage duration\iref{class.dtor}. If +\tcode{std::exit} is called to end a program during the destruction of +an object with static or thread storage duration, the program has undefined +behavior. + +\pnum +\indextext{termination!program}% +\indextext{\idxcode{main} function!return from}% +A return statement in \tcode{main} has the effect of leaving the main +function (destroying any objects with automatic storage duration) and +calling \tcode{std::exit} with the return value as the argument. +If control flows off the end of +the \grammarterm{compound-statement} of \tcode{main}, +the effect is equivalent to a \tcode{return} with operand \tcode{0} +(see also \ref{except.handle}). +\indextext{\idxcode{main} function|)} + +\rSec3[basic.start.static]{Static initialization} + +\pnum +\indextext{initialization}% +\indextext{initialization!static and thread}% +Variables with static storage duration +are initialized as a consequence of program initiation. Variables with +thread storage duration are initialized as a consequence of thread execution. +Within each of these phases of initiation, initialization occurs as follows. + +\pnum +\indextext{initialization!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. +\indextext{initialization!runtime}% +If constant initialization is not performed, a variable with static +storage duration\iref{basic.stc.static} or thread storage +duration\iref{basic.stc.thread} is zero-initialized\iref{dcl.init}. +Together, zero-initialization and constant initialization are called +\indextext{initialization!dynamic}% +\defn{static initialization}; +all other initialization is \defn{dynamic initialization}. +All static initialization strongly happens before\iref{intro.races} +any dynamic initialization. +\begin{note} The dynamic initialization of non-local variables is described +in~\ref{basic.start.dynamic}; that of local static variables is described +in~\ref{stmt.dcl}. \end{note} + +\pnum +An implementation is permitted to perform the initialization of a +variable with static or thread storage duration as a static +initialization even if such initialization is not required to be done +statically, provided that +\begin{itemize} +\item +the dynamic version of the initialization does not change the +value of any other object of static or thread storage duration +prior to its initialization, and + +\item +the static version of the initialization produces the same value +in the initialized variable as would be produced by the dynamic +initialization if all variables not required to be initialized statically +were initialized dynamically. +\end{itemize} +\begin{note} +As a consequence, if the initialization of an object \tcode{obj1} refers to an +object \tcode{obj2} of namespace scope potentially requiring dynamic initialization and defined +later in the same translation unit, it is unspecified whether the value of \tcode{obj2} used +will be the value of the fully initialized \tcode{obj2} (because \tcode{obj2} was statically +initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example, +\begin{codeblock} +inline double fd() { return 1.0; } +extern double d1; +double d2 = d1; // unspecified: + // may be statically initialized to \tcode{0.0} or + // dynamically initialized to \tcode{0.0} if \tcode{d1} is + // dynamically initialized, or \tcode{1.0} otherwise +double d1 = fd(); // may be initialized statically or dynamically to \tcode{1.0} +\end{codeblock} +\end{note} + +\rSec3[basic.start.dynamic]{Dynamic initialization of non-local variables} + +\pnum +\indextext{initialization!dynamic non-local}% +\indextext{start!program}% +\indextext{initialization!order of}% +Dynamic initialization of a non-local variable with static storage duration is +unordered if the variable is an implicitly or explicitly instantiated +specialization, is partially-ordered if the variable +is an inline variable that is not an implicitly or explicitly instantiated +specialization, and otherwise is ordered. +\begin{note} An explicitly specialized non-inline static data member or +variable template specialization has ordered initialization.\end{note} + +\pnum +Dynamic initialization of non-local variables \tcode{V} and \tcode{W} +with static storage duration are ordered as follows: +\begin{itemize} +\item +If \tcode{V} and \tcode{W} have +ordered initialization and \tcode{V} is defined before \tcode{W} within +a single translation unit, the initialization of \tcode{V} is sequenced +before the initialization of \tcode{W}. + +\item +If \tcode{V} has partially-ordered initialization, \tcode{W} does not have +unordered initialization, and \tcode{V} is defined before \tcode{W} in +every translation unit in which \tcode{W} is defined, then +\begin{itemize} +\item +if the program starts a thread\iref{intro.multithread} +other than the main thread\iref{basic.start.main}, +the initialization of \tcode{V} +strongly happens before +the initialization of \tcode{W}; +\item +otherwise, +the initialization of \tcode{V} +is sequenced before +the initialization of \tcode{W}. \end{itemize} -\begin{note} -Historically, lvalues and rvalues were so-called -because they could appear on the left- and right-hand side of an assignment -(although this is no longer generally true); -glvalues are ``generalized'' lvalues, -prvalues are ``pure'' rvalues, -and xvalues are ``eXpiring'' lvalues. -Despite their names, these terms classify expressions, not values. -\end{note} -Every expression belongs to exactly one of the fundamental classifications in this -taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called -its \defn{value category}. \begin{note} The discussion of each built-in operator in -\ref{expr} indicates the category of the value it yields and the value categories -of the operands it expects. For example, the built-in assignment operators expect that -the left operand is an lvalue and that the right operand is a prvalue and yield an -lvalue as the result. User-defined operators are functions, and the categories of -values they expect and yield are determined by their parameter and return types. \end{note} - -\pnum -The \defnx{result}{result!prvalue} of a prvalue -is the value that the expression stores into its context. -A prvalue whose result is the value \placeholder{V} -is sometimes said to have or name the value \placeholder{V}. -The \defn{result object} of a prvalue -is the object initialized by the prvalue; -a prvalue -that is used to compute the value of an operand of an operator or -that has type \cv{}~\tcode{void} -has no result object. -\begin{note} -Except when the prvalue is the operand of a \grammarterm{decltype-specifier}, -a prvalue of class or array type always has a result object. -For a discarded prvalue, a temporary object is materialized; see \ref{expr}. -\end{note} -The \defnx{result}{result!glvalue} of a glvalue is the entity denoted by the expression. -\pnum -\begin{note} -Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted -to a prvalue; see~\ref{conv.lval}, \ref{conv.array}, -and~\ref{conv.func}. -An attempt to bind an rvalue reference to an lvalue is not such a context; see~\ref{dcl.init.ref}. -\end{note} -\begin{note} -There are no prvalue bit-fields; if a bit-field is converted to a -prvalue\iref{conv.lval}, a prvalue of the type of the bit-field is -created, which might then be promoted\iref{conv.prom}. -\end{note} +\item +Otherwise, if the program starts a thread +other than the main thread +before either \tcode{V} or \tcode{W} is initialized, +it is unspecified in which threads +the initializations of \tcode{V} and \tcode{W} occur; +the initializations are unsequenced if they occur in the same thread. -\pnum +\item +Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced. +\end{itemize} \begin{note} -Whenever a prvalue appears in a context where a glvalue is expected, -the prvalue is converted to an xvalue; see~\ref{conv.rval}. +This definition permits initialization of a sequence of +ordered variables concurrently with another sequence. \end{note} \pnum -The discussion of reference initialization in~\ref{dcl.init.ref} and of -temporaries in~\ref{class.temporary} indicates the behavior of lvalues -and rvalues in other significant contexts. - -\pnum -Unless otherwise indicated\iref{expr.call}, -a prvalue shall always have complete type or the \tcode{void} type. -A glvalue shall not have type \cv{}~\tcode{void}. -\begin{note} -A glvalue may have complete or incomplete non-\tcode{void} type. -Class and array prvalues can have cv-qualified types; other prvalues -always have cv-unqualified types. See \ref{expr}. -\end{note} +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% +A \defnx{non-initialization odr-use}{odr-use!non-initialization} +is an odr-use\iref{basic.def.odr} not caused directly or indirectly by +the initialization of a non-local static or thread storage duration variable. \pnum -An lvalue is \defn{modifiable} unless its type is const-qualified -or is a function type. +\indextext{evaluation!unspecified order of}% +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether the dynamic initialization of a +non-local non-inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of any non-inline function or non-inline variable +defined in the same translation unit as the variable to be initialized.% +\footnote{A non-local variable with static storage duration +having initialization +with side effects is initialized in this case, +even if it is not itself odr-used~(\ref{basic.def.odr}, \ref{basic.stc.static}).} +It is \impldef{threads and program points at which deferred dynamic initialization is performed} +in which threads and at which points in the program such deferred dynamic initialization occurs. \begin{note} -A program that attempts -to modify an object through a nonmodifiable lvalue expression or through an rvalue expression -is ill-formed~(\ref{expr.ass}, \ref{expr.post.incr}, \ref{expr.pre.incr}). +Such points should be chosen in a way that allows the programmer to avoid deadlocks. \end{note} +\begin{example} +\begin{codeblock} +// - File 1 - +#include "a.h" +#include "b.h" +B b; +A::A(){ + b.Use(); +} -\pnum -If a program attempts to access the stored value of an object through a glvalue -of other than one of the following types the behavior is -undefined:\footnote{The intent of this list is to specify those circumstances in which an -object may or may not be aliased.} -\begin{itemize} -\item the dynamic type of the object, - -\item a cv-qualified version of the dynamic type of the object, - -\item a type similar (as defined in~\ref{conv.qual}) to the dynamic type -of the object, - -\item a type that is the signed or unsigned type corresponding to the -dynamic type of the object, - -\item a type that is the signed or unsigned type corresponding to a -cv-qualified version of the dynamic type of the object, +// - File 2 - +#include "a.h" +A a; -\item an aggregate or union type that includes one of the aforementioned types among its -elements or non-static data members (including, recursively, an element or non-static data member of a -subaggregate or contained union), +// - File 3 - +#include "a.h" +#include "b.h" +extern A a; +extern B b; -\item a type that is a (possibly cv-qualified) base class type of the dynamic type of -the object, +int main() { + a.Use(); + b.Use(); +} +\end{codeblock} -\item a \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} type. -\end{itemize} +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether either \tcode{a} or \tcode{b} is +initialized before \tcode{main} is entered or whether the +initializations are delayed until \tcode{a} is first odr-used in +\tcode{main}. In particular, if \tcode{a} is initialized before +\tcode{main} is entered, it is not guaranteed that \tcode{b} will be +initialized before it is odr-used by the initialization of \tcode{a}, that +is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized +at some point after the first statement of \tcode{main}, \tcode{b} will +be initialized prior to its use in \tcode{A::A}. \end{example} -\rSec1[basic.align]{Alignment} +\pnum +It is \impldef{dynamic initialization of static inline variables before \tcode{main}} +whether the dynamic initialization of a +non-local inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of that variable. +It is \impldef{threads and program points at which deferred dynamic initialization is performed} +in which threads and at which points in the program such deferred dynamic initialization occurs. \pnum -Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}~(\ref{basic.fundamental}, \ref{basic.compound}) -which place restrictions on the addresses at which an object of that type -may be allocated. An \defn{alignment} is an \impldef{alignment} -integer value representing the number of bytes between successive addresses -at which a given object can be allocated. An object type imposes an alignment -requirement on every object of that type; stricter alignment can be requested -using the alignment specifier\iref{dcl.align}. +It is \impldef{dynamic initialization of thread-local variables before entry} +whether the dynamic initialization of a +non-local non-inline variable with thread storage duration +is sequenced before the first statement of the initial function of a thread or is deferred. +If it is deferred, +the initialization associated with the entity for thread \placeholder{t} +is sequenced before the first non-initialization odr-use by \placeholder{t} +of any non-inline variable with thread storage duration +defined in the same translation unit as the variable to be initialized. +It is \impldef{threads and program points at which deferred dynamic initialization is performed} +in which threads and at which points in the program such deferred dynamic initialization occurs. \pnum -\indextext{alignment!fundamental}% -A \defn{fundamental alignment} is represented by an alignment -less than or equal to the greatest alignment supported by the implementation in -all contexts, which is equal to -\tcode{alignof(std::max_align_t)}\iref{support.types}. -The alignment required for a type might be different when it is used as the type -of a complete object and when it is used as the type of a subobject. \begin{example} -\begin{codeblock} -struct B { long double d; }; -struct D : virtual B { char c; }; -\end{codeblock} +If the initialization of a non-local variable with static or thread storage duration +exits via +an exception, \tcode{std::terminate} is called\iref{except.terminate}.% +\indextext{program!start|)} -When \tcode{D} is the type of a complete object, it will have a subobject of -type \tcode{B}, so it must be aligned appropriately for a \tcode{long double}. -If \tcode{D} appears as a subobject of another object that also has \tcode{B} -as a virtual base class, the \tcode{B} subobject might be part of a different -subobject, reducing the alignment requirements on the \tcode{D} subobject. -\end{example} The result of the \tcode{alignof} operator reflects the alignment -requirement of the type in the complete-object case. +\rSec3[basic.start.term]{Termination} \pnum -\indextext{alignment!extended}% -\indextext{alignment!new-extended}% -\indextext{over-aligned type|see{type, over-aligned}}% -An \defn{extended alignment} is represented by an alignment -greater than \tcode{alignof(std::max_align_t)}. It is \impldef{support for extended alignments} -whether any extended alignments are supported and the contexts in which they are -supported\iref{dcl.align}. A type having an extended alignment -requirement is an \defnx{over-aligned type}{type!over-aligned}. \begin{note} -Every over-aligned type is or contains a class type -to which extended alignment applies (possibly through a non-static data member). +\indextext{program!termination|(}% +\indextext{object!destructor static}% +\indextext{\idxcode{main} function!return from}% +Destructors\iref{class.dtor} for initialized objects +(that is, objects whose lifetime\iref{basic.life} has begun) +with static storage duration, +and functions registered with \tcode{std::atexit}, +are called as part of a call to +\indextext{\idxcode{exit}}% +\indexlibrary{\idxcode{exit}}% +\tcode{std::exit}\iref{support.start.term}. +The call to \tcode{std::exit} is sequenced before +the invocations of the destructors and the registered functions. +\begin{note} +Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. \end{note} -A \defn{new-extended alignment} is represented by -an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. \pnum -Alignments are represented as values of the type \tcode{std::size_t}. -Valid alignments include only those values returned by an \tcode{alignof} -expression for the fundamental types plus an additional \impldef{alignment additional -values} -set of values, which may be empty. -Every alignment value shall be a non-negative integral power of two. +Destructors for initialized objects with thread storage duration within a given thread +are called as a result of returning from the initial function of that thread and as a +result of that thread calling \tcode{std::exit}. +The completions of the destructors for all initialized objects with thread storage +duration within that thread strongly happen before the initiation of the destructors of +any object with static storage duration. \pnum -Alignments have an order from \defnx{weaker}{alignment!weaker} to -\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter -alignments have larger alignment values. An address that satisfies an alignment -requirement also satisfies any weaker valid alignment requirement. +If the completion of the constructor or dynamic initialization of an object with static +storage duration strongly happens before that of another, the completion of the destructor +of the second is sequenced before the initiation of the destructor of the first. +If the completion of the constructor or dynamic initialization of an object with thread +storage duration is sequenced before that of another, the completion of the destructor +of the second is sequenced before the initiation of the destructor of the first. +If an object is +initialized statically, the object is destroyed in the same order as if +the object was dynamically initialized. For an object of array or class +type, all subobjects of that object are destroyed before any block-scope +object with static storage duration initialized during the construction +of the subobjects is destroyed. +If the destruction of an object with static or thread storage duration +exits via an exception, +\tcode{std::terminate} is called\iref{except.terminate}. \pnum -The alignment requirement of a complete type can be queried using an -\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 -underlying type for an aligned memory area\iref{dcl.align}.\end{note} +If a function contains a block-scope object of static or thread storage duration that has been +destroyed and the function is called during the destruction of an object with static or +thread storage duration, the program has undefined behavior if the flow of control +passes through the definition of the previously destroyed block-scope object. Likewise, the +behavior is undefined if the block-scope object is used indirectly (i.e., through a +pointer) after its destruction. \pnum -Comparing alignments is meaningful and provides the obvious results: - -\begin{itemize} -\item Two alignments are equal when their numeric values are equal. -\item Two alignments are different when their numeric values are not equal. -\item When an alignment is larger than another it represents a stricter alignment. -\end{itemize} +\indextext{\idxcode{atexit}}% +\indexlibrary{\idxcode{atexit}}% +If the completion of the initialization of an object with static storage +duration strongly happens before a call to \tcode{std::atexit}~(see +\tcode{}, \ref{support.start.term}), the call to the function passed to +\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a +call to \tcode{std::atexit} strongly happens before the completion of the initialization of +an object with static storage duration, the call to the destructor for the +object is sequenced before the call to the function passed to \tcode{std::atexit}. If a +call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the +call to the function passed to the second \tcode{std::atexit} call is sequenced before +the call to the function passed to the first \tcode{std::atexit} call. \pnum -\begin{note} The runtime pointer alignment function\iref{ptr.align} -can be used to obtain an aligned pointer within a buffer; the aligned-storage templates -in the library\iref{meta.trans.other} can be used to obtain aligned storage. -\end{note} +If there is a use of a standard library object or function not permitted within signal +handlers\iref{support.runtime} that does not happen before\iref{intro.multithread} +completion of destruction of objects with static storage duration and execution of +\tcode{std::atexit} registered functions\iref{support.start.term}, the program has +undefined behavior. \begin{note} If there is a use of an object with static storage +duration that does not happen before the object's destruction, the program has undefined +behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from +\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These +requirements permit thread managers as static-storage-duration objects. \end{note} \pnum -If a request for a specific extended alignment in a specific context is not -supported by an implementation, the program is ill-formed. +\indextext{\idxcode{abort}}% +\indexlibrary{\idxcode{abort}}% +\indextext{termination!program}% +Calling the function \tcode{std::abort()} declared in +\indexhdr{cstdlib}% +\tcode{} terminates the program without executing any destructors +and without calling +the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% +\indextext{program!termination|)} diff --git a/source/classes.tex b/source/classes.tex index 710c95bb5c..6501d65396 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -29,18 +29,18 @@ \begin{bnf} \nontermdef{class-specifier}\br - class-head \terminal{\{} member-specification\opt{} \terminal{\}} + class-head \terminal{\{} \opt{member-specification} \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{class-head}\br - class-key attribute-specifier-seq\opt class-head-name class-virt-specifier\opt base-clause\opt\br - class-key attribute-specifier-seq\opt base-clause\opt + class-key \opt{attribute-specifier-seq} class-head-name \opt{class-virt-specifier} \opt{base-clause}\br + class-key \opt{attribute-specifier-seq} \opt{base-clause} \end{bnf} \begin{bnf} \nontermdef{class-head-name}\br - nested-name-specifier\opt class-name + \opt{nested-name-specifier} class-name \end{bnf} \begin{bnf} @@ -226,16 +226,6 @@ in~\ref{class.mem}.\end{note} \pnum -\indextext{POD struct}\indextext{POD class}\indextext{POD union}% -A \term{POD struct}\footnote{The acronym POD stands for ``plain old data''.} -is a non-union class that is both a trivial class and a -standard-layout class, and has no non-static data members of type non-POD struct, -non-POD union (or array of such types). Similarly, a -\term{POD union} is a union that is both a trivial class and a standard-layout -class, and has no non-static data members of type non-POD struct, non-POD -union (or array of such types). A \term{POD class} is a -class that is either a POD struct or a POD union. - \begin{example} \begin{codeblock} struct N { // neither trivial nor standard-layout @@ -383,7 +373,7 @@ friend Vector operator*(const Matrix&, const Vector&); }; \end{codeblock} -Declaration of \tcode{friend}s is described in~\ref{class.friend}, +Declaration of friends is described in~\ref{class.friend}, operator functions in~\ref{over.oper}. \end{example} \end{note} @@ -441,13 +431,13 @@ \begin{bnf} \nontermdef{member-specification}\br - member-declaration member-specification\opt\br - access-specifier \terminal{:} member-specification\opt + member-declaration \opt{member-specification}\br + access-specifier \terminal{:} \opt{member-specification} \end{bnf} \begin{bnf} \nontermdef{member-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq\opt member-declarator-list\opt{} \terminal{;}\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{member-declarator-list} \terminal{;}\br function-definition\br using-declaration\br static_assert-declaration\br @@ -465,10 +455,10 @@ \begin{bnf} \nontermdef{member-declarator}\br - declarator virt-specifier-seq\opt pure-specifier\opt\br + declarator \opt{virt-specifier-seq} \opt{pure-specifier}\br declarator requires-clause\br - declarator brace-or-equal-initializer\opt\br - identifier\opt{} attribute-specifier-seq\opt{} \terminal{:} constant-expression brace-or-equal-initializer\opt{} + declarator \opt{brace-or-equal-initializer}\br + \opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} \end{bnf} \begin{bnf} @@ -639,10 +629,10 @@ The \grammarterm{member-declarator-list} can be omitted only after a \grammarterm{class-specifier} or an \grammarterm{enum-specifier} or in a -\tcode{friend} declaration\iref{class.friend}. A +friend declaration\iref{class.friend}. A \grammarterm{pure-specifier} shall be used only in the declaration of a virtual function\iref{class.virtual} -that is not a \tcode{friend} declaration. +that is not a friend declaration. \pnum The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{member-declaration} @@ -851,7 +841,7 @@ \begin{note} There can be at most one definition of a non-inline member function in a program. There may be more than one -\tcode{inline} member function definition in a program. +inline member function definition in a program. See~\ref{basic.def.odr} and~\ref{dcl.inline}. \end{note} @@ -889,11 +879,11 @@ \pnum \begin{note} A \tcode{static} local variable or local type in a member function always refers to -the same entity, whether or not the member function is \tcode{inline}. +the same entity, whether or not the member function is inline. \end{note} \pnum -Previously declared member functions may be mentioned in \tcode{friend} declarations. +Previously declared member functions may be mentioned in friend declarations. \pnum \indextext{local class!member function in}% @@ -1314,7 +1304,7 @@ A \grammarterm{member-declarator} of the form \begin{ncbnftab} -identifier\opt{} attribute-specifier-seq\opt{} \terminal{:} constant-expression brace-or-equal-initializer\opt{} +\opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} \end{ncbnftab} \indextext{\idxcode{:}!bit-field declaration}% @@ -1724,7 +1714,7 @@ allowed in a declaration of an anonymous union in a class scope. \indextext{access control!anonymous \tcode{union}}% \indextext{restriction!anonymous \tcode{union}}% -An anonymous union shall not have \tcode{private} or \tcode{protected} +An anonymous union shall not have private or protected members\iref{class.access}. An anonymous union shall not have member functions. @@ -1785,10 +1775,13 @@ \indextext{local class!scope of}% The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. -Declarations in a local class -shall not odr-use\iref{basic.def.odr} a variable with automatic storage -duration from an +\begin{note} +A declaration in a local class +cannot odr-use\iref{basic.def.odr} +a local entity +from an enclosing scope. +\end{note} \begin{example} \indextext{example!local class}% \begin{codeblock} @@ -1798,14 +1791,17 @@ int x; const int N = 5; extern int q(); + int arr[2]; + auto [y, z] = arr; struct local { - int g() { return x; } // error: odr-use of automatic variable \tcode{x} + int g() { return x; } // error: odr-use of non-odr-usable variable \tcode{x} int h() { return s; } // OK int k() { return ::x; } // OK int l() { return q(); } // OK int m() { return N; } // OK: not an odr-use - int* n() { return &N; } // error: odr-use of automatic variable \tcode{N} + int* n() { return &N; } // error: odr-use of non-odr-usable variable \tcode{N} + int p() { return y; } // error: odr-use of non-odr-usable structured binding \tcode{y} }; } diff --git a/source/compatibility.tex b/source/compatibility.tex index 4ceb1fe85f..85e5119db0 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -1,26 +1,26 @@ %!TEX root = std.tex \infannex{diff}{Compatibility} -\rSec1[diff.iso]{\Cpp and ISO C} +\rSec1[diff.iso]{\Cpp{} and ISO C} \pnum \indextext{summary!compatibility with ISO C}% -This subclause lists the differences between \Cpp and +This subclause lists the differences between \Cpp{} and ISO C, by the chapters of this document. \rSec2[diff.lex]{\ref{lex}: lexical conventions} -\ref{lex.key} +\diffref{lex.key} \change New Keywords\\ -New keywords are added to \Cpp; +New keywords are added to \Cpp{}; see \ref{lex.key}. \rationale These keywords were added in order to implement the new -semantics of \Cpp. +semantics of \Cpp{}. \effect Change to semantics of well-defined feature. Any ISO C programs that used any of these keywords as identifiers -are not valid \Cpp programs. +are not valid \Cpp{} programs. \difficulty Syntactic transformation. Converting one specific program is easy. @@ -29,7 +29,7 @@ \howwide Common. -\ref{lex.ccon} +\diffref{lex.ccon} \change Type of character literal is changed from \tcode{int} to \tcode{char}. \rationale This is needed for improved overloaded function argument type @@ -53,13 +53,13 @@ sizeof('x') == sizeof(int) \end{codeblock} -will not work the same as \Cpp programs. +will not work the same as \Cpp{} programs. \difficulty Simple. \howwide Programs which depend upon \tcode{sizeof('x')} are probably rare. -Subclause \ref{lex.string}: +\diffref{lex.string} \change String literals made const.\\ The type of a string literal is changed from ``array of \tcode{char}'' @@ -82,7 +82,7 @@ Syntactic transformation. The fix is to add a cast: \begin{codeblock} -char* p = "abc"; // valid in C, invalid in \Cpp +char* p = "abc"; // valid in C, invalid in \Cpp{} void f(char*) { char* p = (char*)"abc"; // OK: cast added f(p); @@ -96,8 +96,8 @@ \rSec2[diff.basic]{\ref{basic}: basic concepts} -\ref{basic.def} -\change \Cpp does not have ``tentative definitions'' as in C.\\ +\diffref{basic.def} +\change \Cpp{} does not have ``tentative definitions'' as in C.\\ E.g., at file scope, \begin{codeblock} @@ -105,7 +105,7 @@ int i; \end{codeblock} -is valid in C, invalid in \Cpp. +is valid in C, invalid in \Cpp{}. This makes it impossible to define mutually referential file-local static objects, if initializers are restricted to the syntactic forms of C\@. @@ -126,16 +126,16 @@ Deletion of semantically well-defined feature. \difficulty Semantic transformation. -In \Cpp, the initializer for one of a set of +In \Cpp{}, the initializer for one of a set of mutually-referential file-local static objects must invoke a function call to achieve the initialization. \howwide Seldom. -\ref{basic.scope} -\change A \tcode{struct} is a scope in \Cpp, not in C. +\diffref{basic.scope} +\change A \tcode{struct} is a scope in \Cpp{}, not in C. \rationale -Class scope is crucial to \Cpp, and a struct is a class. +Class scope is crucial to \Cpp{}, and a struct is a class. \effect Change to semantics of well-defined feature. \difficulty @@ -146,14 +146,14 @@ names are referred to outside the \tcode{struct}. The latter is probably rare. -\ref{basic.link} [also \ref{dcl.type}] +\diffref{basic.link} [also \ref{dcl.type}] \change A name of file scope that is explicitly declared \tcode{const}, and not explicitly declared \tcode{extern}, has internal linkage, while in C it would have external linkage. \rationale -Because \tcode{const} objects may be used as values during translation in -\Cpp, this feature urges programmers to provide an explicit initializer -for each \tcode{const} object. -This feature allows the user to put \tcode{const} objects in source files that are included +Because const objects may be used as values during translation in +\Cpp{}, this feature urges programmers to provide an explicit initializer +for each const object. +This feature allows the user to put const objects in source files that are included in more than one translation unit. \effect Change to semantics of well-defined feature. @@ -162,7 +162,7 @@ \howwide Seldom. -\ref{basic.start.main} +\diffref{basic.start.main} \change The \tcode{main} function cannot be called recursively and cannot have its address taken. \rationale The \tcode{main} function may require special actions. @@ -174,14 +174,14 @@ \howwide Seldom. -\ref{basic.types} -\change C allows ``compatible types'' in several places, \Cpp does not.\\ +\diffref{basic.types} +\change C allows ``compatible types'' in several places, \Cpp{} does not.\\ For example, otherwise-identical \tcode{struct} types with different tag names are ``compatible'' in C but are distinctly different types -in \Cpp. +in \Cpp{}. \rationale -Stricter type checking is essential for \Cpp. +Stricter type checking is essential for \Cpp{}. \effect Deletion of semantically well-defined feature. \difficulty @@ -197,7 +197,7 @@ \rSec2[diff.conv]{\ref{conv}: standard conversions} -\ref{conv.ptr} +\diffref{conv.ptr} \change Converting \tcode{void*} to a pointer-to-object type requires casting. \begin{codeblock} @@ -210,14 +210,14 @@ ISO C will accept this usage of pointer to void being assigned to a pointer to object type. -\Cpp will not. +\Cpp{} will not. \rationale -\Cpp tries harder than C to enforce compile-time type safety. +\Cpp{} tries harder than C to enforce compile-time type safety. \effect Deletion of semantically well-defined feature. \difficulty Could be automated. -Violations will be diagnosed by the \Cpp translator. +Violations will be diagnosed by the \Cpp{} translator. The fix is to add a cast. For example: @@ -234,10 +234,10 @@ \rSec2[diff.expr]{\ref{expr}: expressions} -\ref{expr.call} +\diffref{expr.call} \change Implicit declaration of functions is not allowed. \rationale -The type-safe nature of \Cpp. +The type-safe nature of \Cpp{}. \effect Deletion of semantically well-defined feature. Note: the original feature was labeled as ``obsolescent'' in ISO C. @@ -248,7 +248,7 @@ \howwide Common. -\ref{expr.post.incr}, \ref{expr.pre.incr} +\diffref{expr.post.incr}, \ref{expr.pre.incr} \change Decrement operator is not allowed with \tcode{bool} operand. \rationale Feature with surprising semantics. @@ -256,7 +256,7 @@ a \tcode{bool} lvalue (for instance, via the C typedef in \tcode{}) is ill-formed in this International Standard. -\ref{expr.sizeof}, \ref{expr.cast} +\diffref{expr.sizeof}, \ref{expr.cast} \change Types must be defined in declarations, not in expressions.\\ In C, a sizeof expression or cast expression may define a new type. For example, @@ -274,13 +274,13 @@ \howwide Seldom. -\ref{expr.cond}, \ref{expr.ass}, \ref{expr.comma} +\diffref{expr.cond}, \ref{expr.ass}, \ref{expr.comma} \indextext{conversion!lvalue-to-rvalue}% \indextext{rvalue!lvalue conversion to}% \indextext{lvalue}% \change The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue. \rationale -\Cpp is an object-oriented language, placing relatively +\Cpp{} is an object-oriented language, placing relatively more emphasis on lvalues. For example, functions may return lvalues. \effect @@ -295,7 +295,7 @@ yields \tcode{100} -in \Cpp and +in \Cpp{} and \tcode{sizeof(char*)} in C. \difficulty @@ -305,7 +305,7 @@ \rSec2[diff.stat]{\ref{stmt.stmt}: statements} -\ref{stmt.switch}, \ref{stmt.goto} +\diffref{stmt.switch}, \ref{stmt.goto} \change It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered). \rationale Constructors used in initializers may allocate @@ -315,7 +315,7 @@ complicated runtime determination of allocation. Furthermore, any use of the uninitialized object could be a disaster. -With this simple compile-time rule, \Cpp assures that +With this simple compile-time rule, \Cpp{} assures that if an initialized variable is in scope, then it has assuredly been initialized. \effect @@ -325,7 +325,7 @@ \howwide Seldom. -\ref{stmt.return} +\diffref{stmt.return} \change It is now invalid to return (explicitly or implicitly) from a function which is declared to return a value without actually returning a value. \rationale @@ -351,15 +351,15 @@ \rSec2[diff.dcl]{\ref{dcl.dcl}: declarations} -\ref{dcl.stc} -\change In \Cpp, the \tcode{static} or \tcode{extern} specifiers can only be applied to names of objects or functions.\\ -Using these specifiers with type declarations is illegal in \Cpp. +\diffref{dcl.stc} +\change In \Cpp{}, the \tcode{static} or \tcode{extern} specifiers can only be applied to names of objects or functions.\\ +Using these specifiers with type declarations is illegal in \Cpp{}. In C, these specifiers are ignored when used on type declarations. Example: \begin{codeblock} -static struct S { // valid C, invalid in \Cpp +static struct S { // valid C, invalid in \Cpp{} int i; }; \end{codeblock} @@ -367,7 +367,7 @@ \rationale Storage class specifiers don't have any meaning when associated with a type. -In \Cpp, class members can be declared with the \tcode{static} storage +In \Cpp{}, class members can be declared with the \tcode{static} storage class specifier. Allowing storage class specifiers on type declarations could render the code confusing for users. @@ -378,10 +378,10 @@ \howwide Seldom. -\ref{dcl.stc} -\change In \Cpp, \tcode{register} is not a storage class specifier. +\diffref{dcl.stc} +\change In \Cpp{}, \tcode{register} is not a storage class specifier. \rationale -The storage class specifier had no effect in \Cpp. +The storage class specifier had no effect in \Cpp{}. \effect Deletion of semantically well-defined feature. \difficulty @@ -389,21 +389,21 @@ \howwide Common. -\ref{dcl.typedef} -\change A \Cpp typedef name must be different from any class type name declared +\diffref{dcl.typedef} +\change A \Cpp{} typedef name must be different from any class type name declared in the same scope (except if the typedef is a synonym of the class name with the same name). In C, a typedef name and a struct tag name declared in the same scope can have the same name (because they have different name spaces). Example: \begin{codeblock} -typedef struct name1 { @\commentellip@ } name1; // valid C and \Cpp +typedef struct name1 { @\commentellip@ } name1; // valid C and \Cpp{} struct name { @\commentellip@ }; -typedef int name; // valid C, invalid \Cpp +typedef int name; // valid C, invalid \Cpp{} \end{codeblock} \rationale -For ease of use, \Cpp doesn't require that a type name be prefixed +For ease of use, \Cpp{} doesn't require that a type name be prefixed with the keywords \tcode{class}, \tcode{struct} or \tcode{union} when used in object declarations or type casts. @@ -421,8 +421,8 @@ \howwide Seldom. -\ref{dcl.type} [see also \ref{basic.link}] -\change \tcode{const} objects must be initialized in \Cpp but can be left uninitialized in C. +\diffref{dcl.type} [see also \ref{basic.link}] +\change const objects must be initialized in \Cpp{} but can be left uninitialized in C. \rationale A const object cannot be assigned to so it must be initialized to hold a useful value. @@ -433,10 +433,10 @@ \howwide Seldom. -\ref{dcl.type} +\diffref{dcl.type} \change Banning implicit \tcode{int}. -In \Cpp a +In \Cpp{} a \grammarterm{decl-specifier-seq} must contain a \grammarterm{type-specifier}{}, unless @@ -445,7 +445,7 @@ In the following example, the left-hand column presents valid C; the right-hand column presents -equivalent \Cpp : +equivalent \Cpp{} : \begin{codeblock} void f(const parm); void f(const int parm); @@ -455,7 +455,7 @@ \end{codeblock} \rationale -In \Cpp, implicit int creates several opportunities for +In \Cpp{}, implicit int creates several opportunities for ambiguity between expressions involving function-like casts and declarations. Explicit declaration is increasingly considered @@ -470,13 +470,13 @@ \howwide Common. -\ref{dcl.spec.auto} +\diffref{dcl.spec.auto} \change The keyword \tcode{auto} cannot be used as a storage class specifier. \begin{codeblock} void f() { - auto int x; // valid C, invalid \Cpp + auto int x; // valid C, invalid \Cpp{} } \end{codeblock} @@ -487,18 +487,18 @@ \difficulty Syntactic transformation. \howwide Rare. -\ref{dcl.enum} -\change \Cpp objects of enumeration type can only be assigned values of the same enumeration type. +\diffref{dcl.enum} +\change \Cpp{} objects of enumeration type can only be assigned values of the same enumeration type. In C, objects of enumeration type can be assigned values of any integral type. Example: \begin{codeblock} enum color { red, blue, green }; -enum color c = 1; // valid C, invalid \Cpp +enum color c = 1; // valid C, invalid \Cpp{} \end{codeblock} \rationale -The type-safe nature of \Cpp. +The type-safe nature of \Cpp{}. \effect Deletion of semantically well-defined feature. \difficulty @@ -508,20 +508,20 @@ \howwide Common. -\ref{dcl.enum} -\change In \Cpp, the type of an enumerator is its enumeration. In C, the type of an enumerator is \tcode{int}. +\diffref{dcl.enum} +\change In \Cpp{}, the type of an enumerator is its enumeration. In C, the type of an enumerator is \tcode{int}. Example: \begin{codeblock} enum e { A }; sizeof(A) == sizeof(int) // in C -sizeof(A) == sizeof(e) // in \Cpp +sizeof(A) == sizeof(e) // in \Cpp{} /* and @sizeof(int)@ is not necessarily equal to @sizeof(e)@ */ \end{codeblock} \rationale -In \Cpp, an enumeration is a distinct type. +In \Cpp{}, an enumeration is a distinct type. \effect Change to semantics of well-defined feature. \difficulty @@ -535,14 +535,14 @@ \rSec2[diff.decl]{\ref{dcl.decl}: declarators} -\ref{dcl.fct} -\change In \Cpp, a function declared with an empty parameter list takes no arguments. +\diffref{dcl.fct} +\change In \Cpp{}, a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown. Example: \begin{codeblock} -int f(); // means \tcode{int f(void)} in \Cpp +int f(); // means \tcode{int f(void)} in \Cpp{} // \tcode{int f(} unknown \tcode{)} in C \end{codeblock} @@ -562,22 +562,22 @@ \howwide Common. -\ref{dcl.fct} [see \ref{expr.sizeof}] -\change In \Cpp, types may not be defined in return or parameter types. +\diffref{dcl.fct} [see \ref{expr.sizeof}] +\change In \Cpp{}, types may not be defined in return or parameter types. In C, these type definitions are allowed. Example: \begin{codeblock} -void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp -enum E { A, B, C } f() {} // valid C, invalid \Cpp +void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp{} +enum E { A, B, C } f() {} // valid C, invalid \Cpp{} \end{codeblock} \rationale -When comparing types in different translation units, \Cpp relies +When comparing types in different translation units, \Cpp{} relies on name equivalence when C relies on structural equivalence. Regarding parameter types: since the type defined in a parameter list -would be in the scope of the function, the only legal calls in \Cpp +would be in the scope of the function, the only legal calls in \Cpp{} would be from within the function itself. \effect Deletion of semantically well-defined feature. @@ -588,8 +588,8 @@ Seldom. This style of type definition is seen as poor coding style. -\ref{dcl.fct.def} -\change In \Cpp, the syntax for function definition excludes the ``old-style'' C function. +\diffref{dcl.fct.def} +\change In \Cpp{}, the syntax for function definition excludes the ``old-style'' C function. In C, ``old-style'' syntax is allowed, but deprecated as ``obsolescent''. \rationale Prototypes are essential to type safety. @@ -600,11 +600,11 @@ \howwide Common in old programs, but already known to be obsolescent. -\ref{dcl.init.aggr} +\diffref{dcl.init.aggr} \change -In \Cpp, designated initialization support is restricted +In \Cpp{}, designated initialization support is restricted compared to the corresponding functionality in C. -In \Cpp, +In \Cpp{}, designators for non-static data members must be specified in declaration order, designators for array elements and nested designators @@ -618,27 +618,27 @@ \begin{codeblock} struct A { int x, y; }; struct B { struct A a; }; -struct A a = {.y = 1, .x = 2}; // valid C, invalid \Cpp -int arr[3] = {[1] = 5}; // valid C, invalid \Cpp -struct B b = {.a.x = 0}; // valid C, invalid \Cpp -struct A c = {.x = 1, 2}; // valid C, invalid \Cpp +struct A a = {.y = 1, .x = 2}; // valid C, invalid \Cpp{} +int arr[3] = {[1] = 5}; // valid C, invalid \Cpp{} +struct B b = {.a.x = 0}; // valid C, invalid \Cpp{} +struct A c = {.x = 1, 2}; // valid C, invalid \Cpp{} \end{codeblock} \rationale -In \Cpp, members are destroyed in reverse construction order +In \Cpp{}, members are destroyed in reverse construction order and the elements of an initializer list are evaluated in lexical order, so field initializers must be specified in order. Array designators conflict with \grammarterm{lambda-expression} syntax. Nested designators are seldom used. \effect -Deletion of feature that is incompatible with \Cpp. +Deletion of feature that is incompatible with \Cpp{}. \difficulty Syntactic transformation. \howwide Out-of-order initializers are common. The other features are seldom used. -\ref{dcl.init.string} -\change In \Cpp, when initializing an array of character with a string, the number of +\diffref{dcl.init.string} +\change In \Cpp{}, when initializing an array of character with a string, the number of characters in the string (including the terminating \tcode{'\textbackslash 0'}) must not exceed the number of elements in the array. In C, an array can be initialized with a string even if the array is not large enough to contain the string-terminating \tcode{'\textbackslash 0'}. @@ -646,7 +646,7 @@ Example: \begin{codeblock} -char array[4] = "abcd"; // valid C, invalid \Cpp +char array[4] = "abcd"; // valid C, invalid \Cpp{} \end{codeblock} \rationale When these non-terminated arrays are manipulated by standard @@ -663,8 +663,8 @@ \rSec2[diff.class]{\ref{class}: classes} -\ref{class.name} [see also \ref{dcl.typedef}] -\change In \Cpp, a class declaration introduces the class name into the scope where it is +\diffref{class.name} [see also \ref{dcl.typedef}] +\change In \Cpp{}, a class declaration introduces the class name into the scope where it is declared and hides any object, function or other declaration of that name in an enclosing scope. In C, an inner scope declaration of a struct tag name never hides the name of an object or function in an outer scope. @@ -676,17 +676,17 @@ void f() { struct x { int a; }; sizeof(x); /* size of the array in C */ - /* size of the struct in @\textit{\textrm{\Cpp}}@ */ + /* size of the struct in @\textit{\textrm{\Cpp{}}}@ */ } \end{codeblock} \rationale -This is one of the few incompatibilities between C and \Cpp that -can be attributed to the new \Cpp name space definition where a +This is one of the few incompatibilities between C and \Cpp{} that +can be attributed to the new \Cpp{} name space definition where a name can be declared as a type and as a non-type in a single scope causing the non-type name to hide the type name and requiring that the keywords \tcode{class}, \tcode{struct}, \tcode{union} or \tcode{enum} be used to refer to the type name. This new name space definition provides important notational -conveniences to \Cpp programmers and helps making the use of the +conveniences to \Cpp{} programmers and helps making the use of the user-defined types as similar as possible to the use of fundamental types. The advantages of the new name space definition were judged to @@ -696,13 +696,13 @@ \difficulty Semantic transformation. If the hidden name that needs to be accessed is at global scope, -the \tcode{::} \Cpp operator can be used. +the \tcode{::} \Cpp{} operator can be used. If the hidden name is at block scope, either the type or the struct tag has to be renamed. \howwide Seldom. -\ref{class.bit} +\diffref{class.bit} \change \indextext{bit-field!implementation-defined sign of}% Bit-fields of type plain \tcode{int} are signed. @@ -712,14 +712,14 @@ the implementation freedom was eliminated for non-dependent types, too. \effect -The choice is implementation-defined in C, but not so in \Cpp. +The choice is implementation-defined in C, but not so in \Cpp{}. \difficulty Syntactic transformation. \howwide Seldom. -\ref{class.nest} -\change In \Cpp, the name of a nested class is local to its enclosing class. In C +\diffref{class.nest} +\change In \Cpp{}, the name of a nested class is local to its enclosing class. In C the name of the nested class belongs to the same scope as the name of the outermost enclosing class. Example: @@ -728,16 +728,16 @@ struct X { struct Y { @\commentellip@ } y; }; -struct Y yy; // valid C, invalid \Cpp +struct Y yy; // valid C, invalid \Cpp{} \end{codeblock} \rationale -\Cpp classes have member functions which require that classes +\Cpp{} classes have member functions which require that classes establish scopes. The C rule would leave classes as an incomplete scope mechanism -which would prevent \Cpp programmers from maintaining locality +which would prevent \Cpp{} programmers from maintaining locality within a class. -A coherent set of scope rules for \Cpp based on the C rule would -be very complicated and \Cpp programmers would be unable to predict +A coherent set of scope rules for \Cpp{} based on the C rule would +be very complicated and \Cpp{} programmers would be unable to predict reliably the meanings of nontrivial examples involving nested or local functions. \effect @@ -764,8 +764,8 @@ \howwide Seldom. -\ref{class.nested.type} -\change In \Cpp, a typedef name may not be redeclared in a class definition after being used in that definition. +\diffref{class.nested.type} +\change In \Cpp{}, a typedef name may not be redeclared in a class definition after being used in that definition. Example: @@ -773,12 +773,12 @@ typedef int I; struct S { I i; - int I; // valid C, invalid \Cpp + int I; // valid C, invalid \Cpp{} }; \end{codeblock} \rationale When classes become complicated, allowing such a redefinition -after the type has been used can create confusion for \Cpp +after the type has been used can create confusion for \Cpp{} programmers as to what the meaning of \tcode{I} really is. \effect Deletion of semantically well-defined feature. @@ -790,7 +790,7 @@ \rSec2[diff.special]{\ref{special}: special member functions} -\ref{class.copy} +\diffref{class.copy} \change Copying volatile objects. The implicitly-declared copy constructor and @@ -801,9 +801,9 @@ \begin{codeblock} struct X { int i; }; volatile struct X x1 = {0}; -struct X x2 = x1; // invalid \Cpp +struct X x2 = x1; // invalid \Cpp{} struct X x3; -x3 = x1; // also invalid \Cpp +x3 = x1; // also invalid \Cpp{} \end{codeblock} \rationale @@ -838,11 +838,11 @@ \rSec2[diff.cpp]{\ref{cpp}: preprocessing directives} -\ref{cpp.predefined} +\diffref{cpp.predefined} \change Whether \mname{STDC} is defined and if so, what its value is, are \impldef{definition and meaning of \mname{STDC}}. \rationale -\Cpp is not identical to ISO C\@. +\Cpp{} is not identical to ISO C\@. Mandating that \mname{STDC} be defined would require that translators make an incorrect claim. Each implementation must choose the behavior that will be most @@ -855,21 +855,21 @@ Programs and headers that reference \mname{STDC} are quite common. -\rSec1[diff.cpp03]{\Cpp and ISO \CppIII} +\rSec1[diff.cpp03]{\Cpp{} and ISO \CppIII{}} \pnum -\indextext{summary!compatibility with ISO \CppIII}% -This subclause lists the differences between \Cpp and -ISO \CppIII (ISO/IEC 14882:2003, \doccite{Programming Languages --- \Cpp}), +\indextext{summary!compatibility with ISO \CppIII{}}% +This subclause lists the differences between \Cpp{} and +ISO \CppIII{} (ISO/IEC 14882:2003, \doccite{Programming Languages --- \Cpp{}}), by the chapters of this document. \rSec2[diff.cpp03.lex]{\ref{lex}: lexical conventions} -\ref{lex.pptoken} +\diffref{lex.pptoken} \change New kinds of string literals. \rationale Required for new features. \effect -Valid \CppIII code may fail to compile or produce different results in +Valid \CppIII{} code may fail to compile or produce different results in this International Standard. Specifically, macros named \tcode{R}, \tcode{u8}, \tcode{u8R}, \tcode{u}, \tcode{uR}, \tcode{U}, \tcode{UR}, or \tcode{LR} will not be expanded when adjacent to a string literal but will be interpreted as @@ -880,11 +880,11 @@ const char* s = u8"def"; // Previously \tcode{"abcdef"}, now \tcode{"def"} \end{codeblock} -\ref{lex.pptoken} +\diffref{lex.pptoken} \change User-defined literal string support. \rationale Required for new features. \effect -Valid \CppIII code may fail to compile or produce different results in +Valid \CppIII{} code may fail to compile or produce different results in this International Standard, as the following example illustrates. \begin{codeblock} @@ -896,7 +896,7 @@ the macro \tcode{_x} would have been expanded. In this International Standard, \#1 consists of a single preprocessing token, so the macro is not expanded. -\ref{lex.key} +\diffref{lex.key} \change New keywords. \rationale Required for new features. \effect @@ -912,10 +912,10 @@ \tcode{static_assert}, and \tcode{thread_local}. -Valid \CppIII code using these identifiers is invalid in this International +Valid \CppIII{} code using these identifiers is invalid in this International Standard. -\ref{lex.icon} +\diffref{lex.icon} \change Type of integer literals. \rationale C99 compatibility. \effect @@ -924,11 +924,11 @@ \rSec2[diff.cpp03.conv]{\ref{conv}: standard conversions} -\ref{conv.ptr} +\diffref{conv.ptr} \change Only literals are integer null pointer constants. \rationale Removing surprising interactions with templates and constant expressions. -\effect Valid \CppIII code may fail to compile or produce different results in +\effect Valid \CppIII{} code may fail to compile or produce different results in this International Standard, as the following example illustrates: \begin{codeblock} @@ -941,19 +941,19 @@ \rSec2[diff.cpp03.expr]{\ref{expr}: expressions} -\ref{expr.mul} +\diffref{expr.mul} \change Specify rounding for results of integer \tcode{/} and \tcode{\%}. \rationale Increase portability, C99 compatibility. \effect -Valid \CppIII code that uses integer division rounds the result toward 0 or +Valid \CppIII{} code that uses integer division rounds the result toward 0 or toward negative infinity, whereas this International Standard always rounds the result toward 0. -\ref{expr.log.and} +\diffref{expr.log.and} \change \tcode{\&\&} is valid in a \grammarterm{type-name}. \rationale Required for new features. \effect -Valid \CppIII code may fail to compile or produce different results in +Valid \CppIII{} code may fail to compile or produce different results in this International Standard, as the following example illustrates: \begin{codeblock} @@ -964,23 +964,23 @@ \rSec2[diff.cpp03.dcl.dcl]{\ref{dcl.dcl}: declarations} -\ref{dcl.spec} +\diffref{dcl.spec} \change Remove \tcode{auto} as a storage class specifier. \rationale New feature. \effect -Valid \CppIII code that uses the keyword \tcode{auto} as a storage class +Valid \CppIII{} code that uses the keyword \tcode{auto} as a storage class specifier may be invalid in this International Standard. In this International Standard, \tcode{auto} indicates that the type of a variable is to be deduced from its initializer expression. \rSec2[diff.cpp03.dcl.decl]{\ref{dcl.decl}: declarators} -\ref{dcl.init.list} +\diffref{dcl.init.list} \change Narrowing restrictions in aggregate initializers. \rationale Catches bugs. \effect -Valid \CppIII code may fail to compile in this International Standard. For -example, the following code is valid in \CppIII but invalid in this +Valid \CppIII{} code may fail to compile in this International Standard. For +example, the following code is valid in \CppIII{} but invalid in this International Standard because \tcode{double} to \tcode{int} is a narrowing conversion: @@ -990,43 +990,43 @@ \rSec2[diff.cpp03.special]{\ref{special}: special member functions} -\ref{class.ctor}, \ref{class.dtor}, \ref{class.copy} +\diffref{class.ctor}, \ref{class.dtor}, \ref{class.copy} \change Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed. \rationale Improves template argument deduction failure. \effect -A valid \CppIII program that uses one of these special member functions in a +A valid \CppIII{} program that uses one of these special member functions in a context where the definition is not required (e.g., in an expression that is not potentially evaluated) becomes ill-formed. -\ref{class.dtor} (destructors) +\diffref{class.dtor} \change User-declared destructors have an implicit exception specification. \rationale Clarification of destructor requirements. \effect -Valid \CppIII code may execute differently in this International Standard. In +Valid \CppIII{} code may execute differently in this International Standard. In particular, destructors that throw exceptions will call \tcode{std::terminate} (without calling \tcode{std::unexpected}) if their exception specification is non-throwing. \rSec2[diff.cpp03.temp]{\ref{temp}: templates} -\ref{temp.param} +\diffref{temp.param} \change Remove \tcode{export}. \rationale No implementation consensus. \effect -A valid \CppIII declaration containing \tcode{export} is ill-formed in this +A valid \CppIII{} declaration containing \tcode{export} is ill-formed in this International Standard. -\ref{temp.arg} +\diffref{temp.arg} \change Remove whitespace requirement for nested closing template right angle brackets. \rationale Considered a persistent but minor annoyance. Template aliases representing non-class types would exacerbate whitespace issues. \effect -Change to semantics of well-defined expression. A valid \CppIII expression +Change to semantics of well-defined expression. A valid \CppIII{} expression containing a right angle bracket (``\tcode{>}'') followed immediately by another right angle bracket may now be treated as closing two templates. -For example, the following code is valid in \CppIII because ``\tcode{>>}'' +For example, the following code is valid in \CppIII{} because ``\tcode{>>}'' is a right-shift operator, but invalid in this International Standard because ``\tcode{>>}'' closes two templates. @@ -1036,30 +1036,30 @@ X< Y< 1 >> 2 > > x; \end{codeblock} -\ref{temp.dep.candidate} +\diffref{temp.dep.candidate} \change Allow dependent calls of functions with internal linkage. \rationale Overly constrained, simplify overload resolution rules. \effect -A valid \CppIII program could get a different result than this +A valid \CppIII{} program could get a different result than this International Standard. \rSec2[diff.cpp03.library]{\ref{library}: library introduction} -\ref{library} -- \ref{\lastlibchapter} +\pnum\textbf{Affected:} \ref{library} -- \ref{\lastlibchapter} \change New reserved identifiers. \rationale Required by new features. \effect -Valid \CppIII code that uses any identifiers added to the \Cpp standard +Valid \CppIII{} code that uses any identifiers added to the \Cpp{} standard library by this International Standard may fail to compile or produce different results in this International Standard. A comprehensive list of identifiers used -by the \Cpp standard library can be found in the Index of Library Names in this +by the \Cpp{} standard library can be found in the Index of Library Names in this International Standard. -\ref{headers} +\diffref{headers} \change New headers. \rationale New functionality. \effect -The following \Cpp headers are new: +The following \Cpp{} headers are new: \tcode{}, \tcode{}, \tcode{}, @@ -1091,28 +1091,28 @@ \tcode{}, and \tcode{}. -Valid \CppIII code that \tcode{\#include}{s} headers with these names may be +Valid \CppIII{} code that \tcode{\#include}{s} headers with these names may be invalid in this International Standard. -\ref{swappable.requirements} +\diffref{swappable.requirements} \effect Function \tcode{swap} moved to a different header \rationale Remove dependency on \tcode{} for \tcode{swap}. -\effect Valid \CppIII code that has been compiled expecting swap to be in +\effect Valid \CppIII{} code that has been compiled expecting swap to be in \tcode{} may have to instead include \tcode{}. -\ref{namespace.posix} +\diffref{namespace.posix} \change New reserved namespace. \rationale New functionality. \effect The global namespace \tcode{posix} is now reserved for standardization. Valid -\CppIII code that uses a top-level namespace \tcode{posix} may be invalid in +\CppIII{} code that uses a top-level namespace \tcode{posix} may be invalid in this International Standard. -\ref{res.on.macro.definitions} +\diffref{res.on.macro.definitions} \change Additional restrictions on macro names. \rationale Avoid hard to diagnose or non-portable constructs. \effect -Names of attribute identifiers may not be used as macro names. Valid \CppIII +Names of attribute identifiers may not be used as macro names. Valid \CppIII{} code that defines \tcode{override}, \tcode{final}, \tcode{carries_dependency}, or \tcode{noreturn} as macros is invalid in this International Standard. @@ -1120,14 +1120,14 @@ \rSec2[diff.cpp03.language.support]{\ref{language.support}: language support library} -\ref{new.delete.single} +\diffref{new.delete.single} \change Linking \tcode{new} and \tcode{delete} operators. \rationale The two throwing single-object signatures of \tcode{operator new} and \tcode{operator delete} are now specified to form the base functionality for the other operators. This clarifies that replacing just these two signatures changes others, even if they are not explicitly changed. \effect -Valid \CppIII code that replaces global \tcode{new} or \tcode{delete} +Valid \CppIII{} code that replaces global \tcode{new} or \tcode{delete} operators may execute differently in this International Standard. For example, the following program should write \tcode{"custom deallocation"} twice, once for the single-object delete and once for the array delete. @@ -1154,80 +1154,80 @@ } \end{codeblock} -\ref{new.delete.single} +\diffref{new.delete.single} \change \tcode{operator new} may throw exceptions other than \tcode{std::bad_alloc}. \rationale Consistent application of \tcode{noexcept}. \effect -Valid \CppIII code that assumes that global \tcode{operator new} only +Valid \CppIII{} code that assumes that global \tcode{operator new} only throws \tcode{std::bad_alloc} may execute differently in this International Standard. \rSec2[diff.cpp03.diagnostics]{\ref{diagnostics}: diagnostics library} -\ref{errno} +\diffref{errno} \change Thread-local error numbers. \rationale Support for new thread facilities. -\effect Valid but implementation-specific \CppIII code that relies on +\effect Valid but implementation-specific \CppIII{} code that relies on \tcode{errno} being the same across threads may change behavior in this International Standard. \rSec2[diff.cpp03.utilities]{\ref{utilities}: general utilities library} -\ref{util.dynamic.safety} +\diffref{util.dynamic.safety} \change Minimal support for garbage-collected regions. \rationale Required by new feature. \effect -Valid \CppIII code, compiled without traceable pointer support, -that interacts with newer \Cpp code using regions declared reachable may +Valid \CppIII{} code, compiled without traceable pointer support, +that interacts with newer \Cpp{} code using regions declared reachable may have different runtime behavior. -\ref{refwrap}, \ref{arithmetic.operations}, \ref{comparisons}, +\diffref{refwrap}, \ref{arithmetic.operations}, \ref{comparisons}, \ref{logical.operations}, \ref{bitwise.operations}, \ref{depr.negators} \change Standard function object types no longer derived from \tcode{std::unary_function} or \tcode{std::binary_function}. \rationale Superseded by new feature; \tcode{unary_function} and \tcode{binary_function} are no longer defined. \effect -Valid \CppIII code that depends on function object types being derived from +Valid \CppIII{} code that depends on function object types being derived from \tcode{unary_function} or \tcode{binary_function} may fail to compile in this International Standard. \rSec2[diff.cpp03.strings]{\ref{strings}: strings library} -\ref{string.classes} +\diffref{string.classes} \change \tcode{basic_string} requirements no longer allow reference-counted strings. \rationale Invalidation is subtly different with reference-counted strings. This change regularizes behavior for this International Standard. \effect -Valid \CppIII code may execute differently in this International Standard. +Valid \CppIII{} code may execute differently in this International Standard. -\ref{string.require} +\diffref{string.require} \change Loosen \tcode{basic_string} invalidation rules. \rationale Allow small-string optimization. \effect -Valid \CppIII code may execute differently in this International Standard. +Valid \CppIII{} code may execute differently in this International Standard. Some \tcode{const} member functions, such as \tcode{data} and \tcode{c_str}, no longer invalidate iterators. \rSec2[diff.cpp03.containers]{\ref{containers}: containers library} -\ref{container.requirements} +\diffref{container.requirements} \change Complexity of \tcode{size()} member functions now constant. \rationale Lack of specification of complexity of \tcode{size()} resulted in divergent implementations with inconsistent performance characteristics. \effect -Some container implementations that conform to \CppIII may not conform to the +Some container implementations that conform to \CppIII{} may not conform to the specified \tcode{size()} requirements in this International Standard. Adjusting containers such as \tcode{std::list} to the stricter requirements may require incompatible changes. -\ref{container.requirements} +\diffref{container.requirements} \change Requirements change: relaxation. \rationale Clarification. \effect -Valid \CppIII code that attempts to meet the specified container requirements +Valid \CppIII{} code that attempts to meet the specified container requirements may now be over-specified. Code that attempted to be portable across containers may need to be adjusted as follows: \begin{itemize} @@ -1237,14 +1237,14 @@ \item not all containers have constant complexity for \tcode{swap()} (\tcode{array}). \end{itemize} -\ref{container.requirements} +\diffref{container.requirements} \change Requirements change: default constructible. \rationale Clarification of container requirements. \effect -Valid \CppIII code that attempts to explicitly instantiate a container using +Valid \CppIII{} code that attempts to explicitly instantiate a container using a user-defined type with no default constructor may fail to compile. -\ref{sequence.reqmts}, \ref{associative.reqmts} +\diffref{sequence.reqmts}, \ref{associative.reqmts} \change Signature changes: from \tcode{void} return types. \rationale Old signature threw away useful information that may be expensive to recalculate. @@ -1257,11 +1257,11 @@ \item \tcode{insert(pos, beg, end)} for \tcode{vector}, \tcode{deque}, \tcode{list}, \tcode{forward_list} \end{itemize} -Valid \CppIII code that relies on these functions returning \tcode{void} +Valid \CppIII{} code that relies on these functions returning \tcode{void} (e.g., code that creates a pointer to member function that points to one of these functions) will fail to compile with this International Standard. -\ref{sequence.reqmts}, \ref{associative.reqmts} +\diffref{sequence.reqmts}, \ref{associative.reqmts} \change Signature changes: from \tcode{iterator} to \tcode{const_iterator} parameters. \rationale Overspecification. @@ -1279,26 +1279,26 @@ \item all forms of \tcode{list::merge} \end{itemize} -Valid \CppIII code that uses these functions may fail to compile with this +Valid \CppIII{} code that uses these functions may fail to compile with this International Standard. -\ref{sequence.reqmts}, \ref{associative.reqmts} +\diffref{sequence.reqmts}, \ref{associative.reqmts} \change Signature changes: \tcode{resize}. \rationale Performance, compatibility with move semantics. \effect For \tcode{vector}, \tcode{deque}, and \tcode{list} the fill value passed to \tcode{resize} is now passed by reference instead of by value, and an additional overload of \tcode{resize} has been added. Valid -\CppIII code that uses this function may fail to compile with this International +\CppIII{} code that uses this function may fail to compile with this International Standard. \rSec2[diff.cpp03.algorithms]{\ref{algorithms}: algorithms library} -\ref{algorithms.general} +\diffref{algorithms.general} \change Result state of inputs after application of some algorithms. \rationale Required by new feature. \effect -A valid \CppIII program may detect that an object with a valid but +A valid \CppIII{} program may detect that an object with a valid but unspecified state has a different valid but unspecified state with this International Standard. For example, \tcode{std::remove} and \tcode{std::remove_if} may leave the tail of the input sequence with a @@ -1306,23 +1306,21 @@ \rSec2[diff.cpp03.numerics]{\ref{numerics}: numerics library} -\ref{complex.numbers} +\diffref{complex.numbers} \change Specified representation of complex numbers. \rationale Compatibility with C99. \effect -Valid \CppIII code that uses implementation-specific knowledge about the +Valid \CppIII{} code that uses implementation-specific knowledge about the binary representation of the required template specializations of \tcode{std::complex} may not be compatible with this International Standard. \rSec2[diff.cpp03.input.output]{\ref{input.output}: input/output library} -\ref{istream::sentry}, -\ref{ostream::sentry}, -\ref{iostate.flags} +\diffref{istream::sentry}, \ref{ostream::sentry}, \ref{iostate.flags} \change Specify use of \tcode{explicit} in existing boolean conversion functions. \rationale Clarify intentions, avoid workarounds. \effect -Valid \CppIII code that relies on implicit boolean conversions will fail to +Valid \CppIII{} code that relies on implicit boolean conversions will fail to compile with this International Standard. Such conversions occur in the following conditions: @@ -1334,22 +1332,22 @@ \item initializing a \tcode{const bool\&} which would bind to a temporary object. \end{itemize} -\ref{ios::failure} +\diffref{ios::failure} \change Change base class of \tcode{std::ios_base::failure}. \rationale More detailed error messages. \effect \tcode{std::ios_base::failure} is no longer derived directly from \tcode{std::exception}, but is now derived from \tcode{std::system_error}, -which in turn is derived from \tcode{std::runtime_error}. Valid \CppIII code +which in turn is derived from \tcode{std::runtime_error}. Valid \CppIII{} code that assumes that \tcode{std::ios_base::failure} is derived directly from \tcode{std::exception} may execute differently in this International Standard. -\ref{ios.base} +\diffref{ios.base} \change Flag types in \tcode{std::ios_base} are now bitmasks with values defined as constexpr static members. \rationale Required for new features. \effect -Valid \CppIII code that relies on \tcode{std::ios_base} flag types being +Valid \CppIII{} code that relies on \tcode{std::ios_base} flag types being represented as \tcode{std::bitset} or as an integer type may fail to compile with this International Standard. For example: @@ -1362,38 +1360,38 @@ } \end{codeblock} -\rSec1[diff.cpp11]{\Cpp and ISO \CppXI} +\rSec1[diff.cpp11]{\Cpp{} and ISO \CppXI{}} \pnum -\indextext{summary!compatibility with ISO \CppXI}% -This subclause lists the differences between \Cpp and -ISO \CppXI (ISO/IEC 14882:2011, \doccite{Programming Languages --- \Cpp}), +\indextext{summary!compatibility with ISO \CppXI{}}% +This subclause lists the differences between \Cpp{} and +ISO \CppXI{} (ISO/IEC 14882:2011, \doccite{Programming Languages --- \Cpp{}}), by the chapters of this document. \rSec2[diff.cpp11.lex]{\ref{lex}: lexical conventions} -\ref{lex.ppnumber} +\diffref{lex.ppnumber} \change \grammarterm{pp-number} can contain one or more single quotes. \rationale Necessary to enable single quotes as digit separators. -\effect Valid \CppXI code may fail to compile or may change meaning in this -International Standard. For example, the following code is valid both in \CppXI and in +\effect Valid \CppXI{} code may fail to compile or may change meaning in this +International Standard. For example, the following code is valid both in \CppXI{} and in this International Standard, but the macro invocation produces different outcomes -because the single quotes delimit a character literal in \CppXI, whereas they are digit +because the single quotes delimit a character literal in \CppXI{}, whereas they are digit separators in this International Standard: \begin{codeblock} #define M(x, ...) __VA_ARGS__ int x[2] = { M(1'2,3'4, 5) }; -// \tcode{int x[2] = \{ 5 \};\ \ \ \ \ } --- \CppXI +// \tcode{int x[2] = \{ 5 \};\ \ \ \ \ } --- \CppXI{} // \tcode{int x[2] = \{ 3'4, 5 \};} --- this International Standard \end{codeblock} \rSec2[diff.cpp11.basic]{\ref{basic}: basic concepts} -\ref{basic.stc.dynamic.deallocation} +\diffref{basic.stc.dynamic.deallocation} \change New usual (non-placement) deallocator. \rationale Required for sized deallocation. -\effect Valid \CppXI code could declare a global placement allocation function and +\effect Valid \CppXI{} code could declare a global placement allocation function and deallocation function as follows: \begin{codeblock} @@ -1409,14 +1407,14 @@ \rSec2[diff.cpp11.expr]{\ref{expr}: expressions} -\ref{expr.cond} +\diffref{expr.cond} \change A conditional expression with a throw expression as its second or third operand keeps the type and value category of the other operand. \rationale Formerly mandated conversions (lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} standard conversions), especially the creation of the temporary due to lvalue-to-rvalue conversion, were considered gratuitous and surprising. -\effect Valid \CppXI code that relies on the conversions may behave differently +\effect Valid \CppXI{} code that relies on the conversions may behave differently in this International Standard: \begin{codeblock} @@ -1431,26 +1429,26 @@ } \end{codeblock} -In \CppXI, \tcode{f(true)} returns \tcode{1}. In this International Standard, +In \CppXI{}, \tcode{f(true)} returns \tcode{1}. In this International Standard, it returns \tcode{2}. \begin{codeblock} sizeof(true ? "" : throw 0) \end{codeblock} -In \CppXI, the expression yields \tcode{sizeof(const char*)}. In this +In \CppXI{}, the expression yields \tcode{sizeof(const char*)}. In this International Standard, it yields \tcode{sizeof(const char[1])}. \rSec2[diff.cpp11.dcl.dcl]{\ref{dcl.dcl}: declarations} -\ref{dcl.constexpr} +\diffref{dcl.constexpr} \change \tcode{constexpr} non-static member functions are not implicitly \tcode{const} member functions. \rationale Necessary to allow \tcode{constexpr} member functions to mutate the object. \effect -Valid \CppXI code may fail to compile in this International Standard. -For example, the following code is valid in \CppXI +Valid \CppXI{} code may fail to compile in this International Standard. +For example, the following code is valid in \CppXI{} but invalid in this International Standard because it declares the same member function twice with different return types: @@ -1463,14 +1461,14 @@ \rSec2[diff.cpp11.dcl.decl]{\ref{dcl.decl}: declarators} -\ref{dcl.init.aggr} +\diffref{dcl.init.aggr} \change Classes with default member initializers can be aggregates. \rationale Necessary to allow default member initializers to be used by aggregate initialization. \effect -Valid \CppXI code may fail to compile or may change meaning in this International Standard. +Valid \CppXI{} code may fail to compile or may change meaning in this International Standard. \begin{codeblock} -struct S { // Aggregate in \CppXIV onwards. +struct S { // Aggregate in \CppXIV{} onwards. int m = 1; }; struct X { @@ -1478,81 +1476,81 @@ operator S(); }; X a{}; -S b{a}; // uses copy constructor in \CppXI, +S b{a}; // uses copy constructor in \CppXI{}, // performs aggregate initialization in this International Standard \end{codeblock} \rSec2[diff.cpp11.library]{\ref{library}: library introduction} -\ref{headers} +\diffref{headers} \change New header. \rationale New functionality. \effect -The \Cpp header \tcode{} is new. -Valid \CppXI code that \tcode{\#include}{s} a header with that name may be +The \Cpp{} header \tcode{} is new. +Valid \CppXI{} code that \tcode{\#include}{s} a header with that name may be invalid in this International Standard. \rSec2[diff.cpp11.input.output]{\ref{input.output}: input/output library} -\ref{c.files} +\diffref{c.files} \change \tcode{gets} is not defined. \rationale Use of \tcode{gets} is considered dangerous. \effect -Valid \CppXI code that uses the \tcode{gets} function may fail to compile +Valid \CppXI{} code that uses the \tcode{gets} function may fail to compile in this International Standard. -\rSec1[diff.cpp14]{\Cpp and ISO \CppXIV} +\rSec1[diff.cpp14]{\Cpp{} and ISO \CppXIV{}} \pnum -\indextext{summary!compatibility with ISO \CppXIV}% -This subclause lists the differences between \Cpp and -ISO \CppXIV (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp}), +\indextext{summary!compatibility with ISO \CppXIV{}}% +This subclause lists the differences between \Cpp{} and +ISO \CppXIV{} (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp{}}), by the chapters of this document. \rSec2[diff.cpp14.lex]{\ref{lex}: lexical conventions} -\ref{lex.phases} +\diffref{lex.phases} \indextext{trigraph sequence}% \change Removal of trigraph support as a required feature. \rationale Prevents accidental uses of trigraphs in non-raw string literals and comments. \effect -Valid \CppXIV code that uses trigraphs may not be valid or may have different +Valid \CppXIV{} code that uses trigraphs may not be valid or may have different semantics in this International Standard. Implementations may choose to -translate trigraphs as specified in \CppXIV if they appear outside of a raw +translate trigraphs as specified in \CppXIV{} if they appear outside of a raw string literal, as part of the \impldef{mapping from physical source file characters to basic source character set} mapping from physical source file characters to the basic source character set. -\ref{lex.ppnumber} +\diffref{lex.ppnumber} \change \grammarterm{pp-number} can contain \tcode{p} \grammarterm{sign} and \tcode{P} \grammarterm{sign}. \rationale Necessary to enable hexadecimal floating literals. \effect -Valid \CppXIV code may fail to compile or produce different results in +Valid \CppXIV{} code may fail to compile or produce different results in this International Standard. Specifically, character sequences like \tcode{0p+0} -and \tcode{0e1_p+0} are three separate tokens each in \CppXIV, but one single token +and \tcode{0e1_p+0} are three separate tokens each in \CppXIV{}, but one single token in this International Standard. \begin{codeblock} #define F(a) b ## a -int b0p = F(0p+0); // ill-formed; equivalent to ``\tcode{int b0p = b0p + 0;}\!'' in \CppXIV +int b0p = F(0p+0); // ill-formed; equivalent to ``\tcode{int b0p = b0p + 0;}\!'' in \CppXIV{} \end{codeblock} \rSec2[diff.cpp14.expr]{\ref{expr}: expressions} -\ref{expr.post.incr}, \ref{expr.pre.incr} +\diffref{expr.post.incr}, \ref{expr.pre.incr} \change Remove increment operator with \tcode{bool} operand. \rationale Obsolete feature with occasionally surprising semantics. -\effect A valid \CppXIV expression utilizing the increment operator on +\effect A valid \CppXIV{} expression utilizing the increment operator on a \tcode{bool} lvalue is ill-formed in this International Standard. Note that this might occur when the lvalue has a type given by a template parameter. -\ref{expr.new}, \ref{expr.delete} +\diffref{expr.new}, \ref{expr.delete} \change Dynamic allocation mechanism for over-aligned types. \rationale Simplify use of over-aligned types. -\effect In \CppXIV code that uses a \grammarterm{new-expression} +\effect In \CppXIV{} code that uses a \grammarterm{new-expression} to allocate an object with an over-aligned class type, where that class has no allocation functions of its own, \tcode{::operator new(std::size_t)} @@ -1563,20 +1561,20 @@ \rSec2[diff.cpp14.dcl.dcl]{\ref{dcl.dcl}: declarations} -\ref{dcl.stc} +\diffref{dcl.stc} \indextext{\idxcode{register} storage class}% \change Removal of \tcode{register} \grammarterm{storage-class-specifier}. \rationale Enable repurposing of deprecated keyword in future revisions of this International Standard. \effect -A valid \CppXIV declaration utilizing the \tcode{register} +A valid \CppXIV{} declaration utilizing the \tcode{register} \grammarterm{storage-class-specifier} is ill-formed in this International Standard. The specifier can simply be removed to retain the original meaning. -\ref{dcl.spec.auto} +\diffref{dcl.spec.auto} \change \tcode{auto} deduction from \grammarterm{braced-init-list}. \rationale More intuitive deduction behavior. \effect -Valid \CppXIV code may fail to compile or may change meaning +Valid \CppXIV{} code may fail to compile or may change meaning in this International Standard. For example: \begin{codeblock} auto x1{1}; // was \tcode{std::initializer_list}, now \tcode{int} @@ -1585,11 +1583,11 @@ \rSec2[diff.cpp14.decl]{\ref{dcl.decl}: declarators} -\ref{dcl.fct} +\diffref{dcl.fct} \change Make exception specifications be part of the type system. \rationale Improve type-safety. \effect -Valid \CppXIV code may fail to compile or change meaning in this +Valid \CppXIV{} code may fail to compile or change meaning in this International Standard: \begin{codeblock} @@ -1599,12 +1597,12 @@ int x = f(g1, g2); // ill-formed; previously well-formed \end{codeblock} -\ref{dcl.init.aggr} +\diffref{dcl.init.aggr} \change Definition of an aggregate is extended to apply to user-defined types with base classes. \rationale To increase convenience of aggregate initialization. \effect -Valid \CppXIV code may fail to compile or produce different results in this +Valid \CppXIV{} code may fail to compile or produce different results in this International Standard; initialization from an empty initializer list will perform aggregate initialization instead of invoking a default constructor for the affected types: @@ -1617,19 +1615,19 @@ }; struct derived : base {}; -derived d1{}; // error; the code was well-formed in \CppXIV +derived d1{}; // error; the code was well-formed in \CppXIV{} derived d2; // still OK \end{codeblock} \rSec2[diff.cpp14.special]{\ref{special}: special member functions} -\ref{class.inhctor.init} +\diffref{class.inhctor.init} \change Inheriting a constructor no longer injects a constructor into the derived class. \rationale Better interaction with other language features. \effect -Valid \CppXIV code that uses inheriting constructors may not be valid +Valid \CppXIV{} code that uses inheriting constructors may not be valid or may have different semantics. A \grammarterm{using-declaration} that names a constructor now makes the corresponding base class constructors visible to initializations of the derived class @@ -1650,13 +1648,13 @@ \rSec2[diff.cpp14.temp]{\ref{temp}: templates} -\ref{temp.deduct.type} +\diffref{temp.deduct.type} \change Allowance to deduce from the type of a non-type template argument. \rationale In combination with the ability to declare non-type template arguments with placeholder types, allows partial specializations to decompose from the type deduced for the non-type template argument. -\effect Valid \CppXIV code may fail to compile +\effect Valid \CppXIV{} code may fail to compile or produce different results in this International Standard: \begin{codeblock} template struct A; @@ -1669,7 +1667,7 @@ \rSec2[diff.cpp14.except]{\ref{except}: exception handling} -\ref{except.spec} +\diffref{except.spec} \change Remove dynamic exception specifications. \rationale Dynamic exception specifications were a deprecated feature that was complex and brittle in use. @@ -1677,7 +1675,7 @@ which became a more significant issue in this International Standard where (non-dynamic) exception specifications are part of the function type. \effect -A valid \CppXIV function declaration, +A valid \CppXIV{} function declaration, member function declaration, function pointer declaration, or function reference declaration, @@ -1690,11 +1688,11 @@ \rSec2[diff.cpp14.library]{\ref{library}: library introduction} -\ref{headers} +\diffref{headers} \change New headers. \rationale New functionality. \effect -The following \Cpp headers are new: +The following \Cpp{} headers are new: \tcode{}, \tcode{}, \tcode{}, @@ -1703,10 +1701,10 @@ \tcode{}, and \tcode{}. -Valid \CppXIV code that \tcode{\#include}{s} headers with these names may be +Valid \CppXIV{} code that \tcode{\#include}{s} headers with these names may be invalid in this International Standard. -\ref{namespace.future} +\diffref{namespace.future} \change New reserved namespaces. \rationale Reserve namespaces for future revisions of the standard library that might otherwise be incompatible with existing programs. @@ -1714,26 +1712,26 @@ The global namespaces \tcode{std} followed by an arbitrary sequence of digits is reserved for future standardization. -Valid \CppXIV code that uses such a top-level namespace, +Valid \CppXIV{} code that uses such a top-level namespace, e.g., \tcode{std2}, may be invalid in this International Standard. \rSec2[diff.cpp14.utilities]{\ref{utilities}: general utilities library} -\ref{func.wrap} +\diffref{func.wrap} \change Constructors taking allocators removed. \rationale No implementation consensus. \effect -Valid \CppXIV code may fail to compile or may change meaning in this +Valid \CppXIV{} code may fail to compile or may change meaning in this International Standard. Specifically, constructing a \tcode{std::function} with an allocator is ill-formed and uses-allocator construction will not pass an allocator to \tcode{std::function} constructors in this International Standard. -\ref{util.smartptr.shared} +\diffref{util.smartptr.shared} \change Different constraint on conversions from \tcode{unique_ptr}. \rationale Adding array support to \tcode{shared_ptr}, via the syntax \tcode{shared_ptr} and \tcode{shared_ptr}. \effect -Valid \CppXIV code may fail to compile or may change meaning in this +Valid \CppXIV{} code may fail to compile or may change meaning in this International Standard. For example: @@ -1745,7 +1743,7 @@ \rSec2[diff.cpp14.string]{\ref{strings}: strings library} -\ref{basic.string} +\diffref{basic.string} \change Non-const \tcode{.data()} member added. \rationale The lack of a non-const \tcode{.data()} differed from the similar member of \tcode{std::vector}. @@ -1766,11 +1764,11 @@ \rSec2[diff.cpp14.containers]{\ref{containers}: containers library} -\ref{associative.reqmts} +\diffref{associative.reqmts} \change Requirements change: \rationale Increase portability, clarification of associative container requirements. \effect -Valid \CppXIV code that attempts to use associative containers +Valid \CppXIV{} code that attempts to use associative containers having a comparison object with non-const function call operator may fail to compile in this International Standard: @@ -1808,37 +1806,107 @@ \tcode{bind2nd} are not defined. \rationale Superseded by new features. -\effect Valid \CppXIV code that uses these class templates +\effect Valid \CppXIV{} code that uses these class templates and function templates may fail to compile in this International Standard. \change Remove old iostreams members [depr.ios.members]. \rationale Redundant feature for compatibility with pre-standard code has served its time. -\effect A valid \CppXIV program using these identifiers +\effect A valid \CppXIV{} program using these identifiers may be ill-formed in this International Standard. -\rSec1[diff.cpp17]{\Cpp and ISO \CppXVII} +\rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}} \pnum -\indextext{summary!compatibility with ISO \CppXVII}% -This subclause lists the differences between \Cpp and -ISO \CppXVII (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp}), +\indextext{summary!compatibility with ISO \CppXVII{}}% +This subclause lists the differences between \Cpp{} and +ISO \CppXVII{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}), by the chapters of this document. \rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions} -\ref{lex.key} -\change New keywords.\\ +\diffref{lex.key} +\change New keywords. \rationale Required for new features. 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} +Valid ISO \CppXVII{} code using \tcode{concept} or \tcode{requires} as an identifier is not valid in this International Standard. +\diffref{lex.operators} +\change New operator \tcode{<=>}. +\rationale Necessary for new functionality. +\effect Valid \CppXVII{} code that contains a \tcode{<=} token +immediately followed by a \tcode{>} token +may be ill-formed or have different semantics in this International Standard: +\begin{codeblock} +namespace N { + struct X {}; + bool operator<=(X, X); + template struct Y {}; + Y y; // ill-formed; previously well-formed +} +\end{codeblock} + +\rSec2[diff.cpp17.expr]{\ref{expr}: expressions} + +\diffref{expr.prim.lambda.capture} +\change Implicit lambda capture may capture additional entities. +\rationale Rule simplification, necessary to resolve interactions with constexpr if. +\effect Lambdas with a \grammarterm{capture-default} +may capture local entities +that were not captured in \CppXVII{} +if those entities are only referenced in contexts +that do not result in an odr-use. + +\rSec2[diff.cpp17.temp]{\ref{temp}: templates} + +\diffref{temp.names} +\change +An \grammarterm{unqualified-id} +that is followed by a \tcode{<} +and for which name lookup +finds nothing or finds a function +will be treated as a \grammarterm{template-name} +in order to potentially cause argument dependent lookup to be performed. +\rationale +It was problematic to call a function template +with an explicit template argument list +via argument dependent lookup +because of the need to have a template with the same name +visible via normal lookup. +\effect +Previously valid code that uses a function name +as the left operand of a \tcode{<} operator +would become ill-formed. +\begin{codeblock} +struct A {}; +bool operator<(void (*fp)(), A); +void f() {} +int main() { + A a; + f < a; // ill-formed; previously well-formed + (f) < a; // still well formed +} +\end{codeblock} + +\rSec2[diff.cpp17.library]{\ref{library}: library introduction} + +\ref{headers} +\change New headers. +\rationale New functionality. +\effect +The following \Cpp{} headers are new: +\tcode{} +and +\tcode{}. +Valid \CppXVII{} code that \tcode{\#include}{s} headers with these names may be +invalid in this International Standard. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \rSec1[diff.library]{C standard library} \indextext{library!C standard}% @@ -1846,37 +1914,37 @@ \pnum This subclause summarizes the explicit changes in headers, definitions, declarations, or behavior between the C standard library -in the C standard and the parts of the \Cpp standard library that were +in the C standard and the parts of the \Cpp{} standard library that were included from the C standard library. \rSec2[diff.mods.to.headers]{Modifications to headers} \pnum For compatibility with the C standard library\indextext{library!C standard}, -the \Cpp standard library provides the C headers enumerated -in~\ref{depr.c.headers}, but their use is deprecated in \Cpp. +the \Cpp{} standard library provides the C headers enumerated +in~\ref{depr.c.headers}, but their use is deprecated in \Cpp{}. \pnum -There are no \Cpp headers for the C headers -\tcode{}\indextext{\idxhdr{stdatomic.h}}, -\tcode{}\indextext{\idxhdr{stdnoreturn.h}}, -and \tcode{}\indextext{\idxhdr{threads.h}}, -nor are the C headers themselves part of \Cpp. +There are no \Cpp{} headers for the C headers +\tcode{}\indexhdr{stdatomic.h}, +\tcode{}\indexhdr{stdnoreturn.h}, +and \tcode{}\indexhdr{threads.h}, +nor are the C headers themselves part of \Cpp{}. \pnum -The \Cpp headers \tcode{}\indextext{\idxhdr{ccomplex}}\iref{depr.ccomplex.syn} -and \tcode{}\indextext{\idxhdr{ctgmath}}\iref{depr.ctgmath.syn}, as well -as their corresponding C headers \tcode{}\indextext{\idxhdr{complex.h}} -and \tcode{}\indextext{\idxhdr{tgmath.h}}, do not contain any of the +The \Cpp{} headers \tcode{}\indexhdr{ccomplex}\iref{depr.ccomplex.syn} +and \tcode{}\indexhdr{ctgmath}\iref{depr.ctgmath.syn}, as well +as their corresponding C headers \tcode{}\indexhdr{complex.h} +and \tcode{}\indexhdr{tgmath.h}, do not contain any of the content from the C standard library and instead merely include other headers -from the \Cpp standard library. +from the \Cpp{} standard library. \pnum -The headers \tcode{}\indextext{\idxhdr{ciso646}}, -\tcode{}\indextext{\idxhdr{cstdalign}}\iref{depr.cstdalign.syn}, -and \tcode{}\indextext{\idxhdr{cstdbool}}\iref{depr.cstdbool.syn} -are meaningless in \Cpp. Use of -the \Cpp headers \tcode{}, \tcode{}, \tcode{}, +The headers \tcode{}\indexhdr{ciso646}, +\tcode{}\indexhdr{cstdalign}\iref{depr.cstdalign.syn}, +and \tcode{}\indexhdr{cstdbool}\iref{depr.cstdbool.syn} +are meaningless in \Cpp{}. Use of +the \Cpp{} headers \tcode{}, \tcode{}, \tcode{}, and \tcode{} is deprecated\iref{depr.c.headers}. \rSec2[diff.mods.to.definitions]{Modifications to definitions} @@ -1889,7 +1957,7 @@ The tokens \tcode{char16_t} and \tcode{char32_t} are keywords in this International Standard\iref{lex.key}. They do not appear as macro names defined in -\tcode{}\indexlibrary{\idxhdr{cuchar}}\iref{cuchar.syn}. +\tcode{}\indexhdr{cuchar}\iref{cuchar.syn}. \rSec3[diff.wchar.t]{Type \tcode{wchar_t}} @@ -1899,20 +1967,20 @@ The token \tcode{wchar_t} is a keyword in this International Standard\iref{lex.key}. It does not appear as a type name defined in any of -\tcode{}\iref{cstddef.syn}\indexlibrary{\idxhdr{cstddef}}, -\tcode{}\iref{cstdlib.syn}\indexlibrary{\idxhdr{cstdlib}}, -or \tcode{}\iref{cwchar.syn}\indexlibrary{\idxhdr{cwchar}}. +\tcode{}\iref{cstddef.syn}\indexhdr{cstddef}, +\tcode{}\iref{cstdlib.syn}\indexhdr{cstdlib}, +or \tcode{}\iref{cwchar.syn}\indexhdr{cwchar}. \rSec3[diff.header.assert.h]{Header \tcode{}} -\indexlibrary{\idxhdr{assert.h}}% +\indexhdr{assert.h}% \pnum The token \tcode{static_assert} is a keyword in this International Standard\iref{lex.key}. It does not appear as a macro name defined -in \tcode{}\indexlibrary{\idxhdr{cassert}}\iref{cassert.syn}. +in \tcode{}\indexhdr{cassert}\iref{cassert.syn}. \rSec3[diff.header.iso646.h]{Header \tcode{}} -\indexlibrary{\idxhdr{iso646.h}}% +\indexhdr{iso646.h}% \pnum The tokens @@ -1932,24 +2000,24 @@ Standard\iref{lex.key}. They do not appear as macro names defined in \tcode{}. -\indexlibrary{\idxhdr{ciso646}}% +\indexhdr{ciso646}% \rSec3[diff.header.stdalign.h]{Header \tcode{}} -\indexlibrary{\idxhdr{stdalign.h}}% +\indexhdr{stdalign.h}% \pnum The token \tcode{alignas} is a keyword in this International Standard\iref{lex.key}. It does not appear as a macro name defined -in \tcode{}\indexlibrary{\idxhdr{cstdalign}}\iref{depr.cstdalign.syn}. +in \tcode{}\indexhdr{cstdalign}\iref{depr.cstdalign.syn}. \rSec3[diff.header.stdbool.h]{Header \tcode{}} -\indexlibrary{\idxhdr{stdbool.h}}% +\indexhdr{stdbool.h}% \pnum The tokens \tcode{bool}, \tcode{true}, and \tcode{false} are keywords in this International Standard\iref{lex.key}. They do not appear as macro names defined in -\tcode{}\indexlibrary{\idxhdr{cstdbool}}\iref{depr.cstdbool.syn}. +\tcode{}\indexhdr{cstdbool}\iref{depr.cstdbool.syn}. \rSec3[diff.null]{Macro \tcode{NULL}} @@ -1957,20 +2025,20 @@ The macro \tcode{NULL}, defined in any of -\tcode{}\iref{c.locales}\indexlibrary{\idxhdr{clocale}}, -\tcode{}\iref{cstddef.syn}\indexlibrary{\idxhdr{cstddef}}, -\tcode{}\iref{cstdio.syn}\indexlibrary{\idxhdr{cstdio}}, -\tcode{}\iref{cstdlib.syn}\indexlibrary{\idxhdr{cstdlib}}, -\tcode{}\iref{cstring.syn}\indexlibrary{\idxhdr{cstring}}, -\tcode{}\iref{ctime.syn}\indexlibrary{\idxhdr{ctime}}, -or \tcode{}\iref{cwchar.syn}\indexlibrary{\idxhdr{cwchar}}, -is an \impldef{definition of \tcode{NULL}} \Cpp null pointer constant in +\tcode{}\iref{c.locales}\indexhdr{clocale}, +\tcode{}\iref{cstddef.syn}\indexhdr{cstddef}, +\tcode{}\iref{cstdio.syn}\indexhdr{cstdio}, +\tcode{}\iref{cstdlib.syn}\indexhdr{cstdlib}, +\tcode{}\iref{cstring.syn}\indexhdr{cstring}, +\tcode{}\iref{ctime.syn}\indexhdr{ctime}, +or \tcode{}\iref{cwchar.syn}\indexhdr{cwchar}, +is an \impldef{definition of \tcode{NULL}} \Cpp{} null pointer constant in this International Standard\iref{support.types}. \rSec2[diff.mods.to.declarations]{Modifications to declarations} \pnum -Header \tcode{}\iref{cstring.syn}\indexlibrary{\idxhdr{cstring}}: +Header \tcode{}\iref{cstring.syn}\indexhdr{cstring}: The following functions have different declarations: \begin{itemize} @@ -1984,7 +2052,7 @@ Subclause \ref{cstring.syn} describes the changes. \pnum -Header \tcode{}\iref{cwchar.syn}\indexlibrary{\idxhdr{cwchar}}: +Header \tcode{}\iref{cwchar.syn}\indexhdr{cwchar}: The following functions have different declarations: \begin{itemize} @@ -1998,14 +2066,14 @@ Subclause \ref{cwchar.syn} describes the changes. \pnum -Header \tcode{}\iref{cstddef.syn}\indexlibrary{\idxhdr{cstddef}} +Header \tcode{}\iref{cstddef.syn}\indexhdr{cstddef} declares the name \tcode{nullptr_t} in addition to the names declared in \tcode{} in the C standard library. \rSec2[diff.mods.to.behavior]{Modifications to behavior} \pnum -Header \tcode{}\iref{cstdlib.syn}\indexlibrary{\idxhdr{cstdlib}}: +Header \tcode{}\iref{cstdlib.syn}\indexhdr{cstdlib}: The following functions have different behavior: \begin{itemize} @@ -2017,7 +2085,7 @@ Subclause \ref{support.start.term} describes the changes. \pnum -Header \tcode{}\iref{csetjmp.syn}\indexlibrary{\idxhdr{csetjmp}}: +Header \tcode{}\iref{csetjmp.syn}\indexhdr{csetjmp}: The following functions have different behavior: \begin{itemize} @@ -2031,7 +2099,7 @@ \pnum The macro \tcode{offsetof}, defined in -\tcode{}\iref{cstddef.syn}\indexlibrary{\idxhdr{cstddef}}, +\tcode{}\iref{cstddef.syn}\indexhdr{cstddef}, accepts a restricted set of \tcode{\placeholder{type}} arguments in this International Standard. Subclause \ref{support.types.layout} describes the change. diff --git a/source/config.tex b/source/config.tex index 7da85d6d87..42834979c9 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4700} -\newcommand{\prevdocno}{N4687} +\newcommand{\docno}{N4713} +\newcommand{\prevdocno}{N4700} \newcommand{\cppver}{201703L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index b1c6112978..1cc00dc7fd 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -4,7 +4,7 @@ \rSec1[containers.general]{General} \pnum -This Clause describes components that \Cpp programs may use to +This Clause describes components that \Cpp{} programs may use to organize collections of information. \pnum @@ -994,7 +994,7 @@ \begin{itemize} \item If the constructor \begin{codeblock} -template +template X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); \end{codeblock} @@ -1004,14 +1004,14 @@ \item If the member functions of the forms: \begin{codeblock} -template +template @\placeholdernc{return-type}@ @\placeholdernc{F}@(const_iterator p, InputIterator first, InputIterator last); // such as \tcode{insert} -template +template @\placeholdernc{return-type}@ @\placeholdernc{F}@(InputIterator first, InputIterator last); // such as \tcode{append}, \tcode{assign} -template +template @\placeholdernc{return-type}@ @\placeholdernc{F}@(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last); // such as \tcode{replace} \end{codeblock} @@ -1266,7 +1266,7 @@ allocator_type get_allocator() const; explicit operator bool() const noexcept; - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; void swap(@\placeholdernc{node_handle}@&) noexcept(ator_traits::propagate_on_container_swap::value || @@ -1421,7 +1421,7 @@ \end{itemdescr} \begin{itemdecl} -bool empty() const noexcept; +[[nodiscard]] bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -1457,7 +1457,7 @@ That return type is a specialization of the type specified in this subclause. \begin{codeblock} -template +template struct @\placeholder{INSERT_RETURN_TYPE}@ { Iterator position; @@ -2509,7 +2509,7 @@ & \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Equivalent to a.insert(t). Return value is an iterator pointing + \effects Equivalent to \tcode{a.insert(t)}. Return value is an iterator pointing to the element with the key equivalent to that of \tcode{t}. The iterator \tcode{p} is a hint pointing to where the search should start. Implementations are permitted to ignore the hint.% @@ -2521,8 +2521,8 @@ \tcode{a.insert(i, j)} & \tcode{void} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \requires \tcode{i} and \tcode{j} are not iterators in \tcode{a}. - Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% + \requires \tcode{i} and \tcode{j} are not iterators in \tcode{a}.\br + \effects Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% \indextext{unordered associative containers!\idxcode{insert}}% \indextext{\idxcode{insert}!unordered associative containers}% & Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. @@ -2603,8 +2603,7 @@ refer to those same elements but as members of \tcode{a}. Iterators referring to the transferred elements and all iterators referring to \tcode{a} will be invalidated, but iterators to elements remaining in \tcode{a2} will - remain valid.\br - \throws{} Nothing unless the hash function or key equality predicate throws. & + remain valid. & Average case \bigoh{N}, where $N$ is \tcode{a2.size()}. Worst case \bigoh{N\tcode{*a.size()}\br\tcode{+} N}. \\ \rowsep % @@ -2747,8 +2746,9 @@ \tcode{b.cbegin(n)} & \tcode{const_local_iterator} & \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - Note: \tcode{[b.cbegin(n), b.cend(n))} is a valid range containing - all of the elements in the $\texttt{n}^{\textrm{ th}}$ bucket.% + \tcode{b.cbegin(n)} returns an iterator referring to the + first element in the bucket. If the bucket is empty, then + \tcode{b.cbegin(n) == b.cend(n)}.% \indextext{unordered associative containers!\idxcode{cbegin}}% \indextext{\idxcode{cbegin}!unordered associative containers}% & Constant @@ -2757,6 +2757,8 @@ \tcode{b.cend(n)} & \tcode{const_local_iterator} & \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}.% + \tcode{b.cend(n)} returns an iterator which is the past-the-end + value for the bucket.% \indextext{unordered associative containers!\idxcode{cend}}% \indextext{\idxcode{cend}!unordered associative containers}% & Constant @@ -2924,78 +2926,76 @@ \rSec2[array.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{array}}% -\indexlibrary{\idxhdr{array}}% +\indexhdr{array}% \begin{codeblock} #include namespace std { // \ref{array}, class template \tcode{array} - template struct array; + template struct array; - template + template bool operator==(const array& x, const array& y); - template + template bool operator!=(const array& x, const array& y); - template + template bool operator< (const array& x, const array& y); - template + template bool operator> (const array& x, const array& y); - template + template bool operator<=(const array& x, const array& y); - template + template bool operator>=(const array& x, const array& y); - template + template void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); - template class tuple_size; - template class tuple_element; - template + template class tuple_size; + template class tuple_element; + template struct tuple_size>; - template + template struct tuple_element>; - template + template constexpr T& get(array&) noexcept; - template + template constexpr T&& get(array&&) noexcept; - template + template constexpr const T& get(const array&) noexcept; - template + template constexpr const T&& get(const array&&) noexcept; } \end{codeblock} \rSec2[deque.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{deque}}% -\indexlibrary{\idxhdr{deque}}% +\indexhdr{deque}% \begin{codeblock} #include namespace std { // \ref{deque}, class template \tcode{deque} - template > class deque; + template> class deque; - template + template bool operator==(const deque& x, const deque& y); - template + template bool operator< (const deque& x, const deque& y); - template + template bool operator!=(const deque& x, const deque& y); - template + template bool operator> (const deque& x, const deque& y); - template + template bool operator>=(const deque& x, const deque& y); - template + template bool operator<=(const deque& x, const deque& y); - template + template void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template + template using deque = std::deque>; } } @@ -3003,35 +3003,34 @@ \rSec2[forward_list.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{forward_list}}% -\indexlibrary{\idxhdr{forward_list}}% +\indexhdr{forward_list}% \begin{codeblock} #include namespace std { // \ref{forwardlist}, class template \tcode{forward_list} - template > class forward_list; + template> class forward_list; - template + template bool operator==(const forward_list& x, const forward_list& y); - template + template bool operator< (const forward_list& x, const forward_list& y); - template + template bool operator!=(const forward_list& x, const forward_list& y); - template + template bool operator> (const forward_list& x, const forward_list& y); - template + template bool operator>=(const forward_list& x, const forward_list& y); - template + template bool operator<=(const forward_list& x, const forward_list& y); - template + template void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template + template using forward_list = std::forward_list>; } } @@ -3039,35 +3038,34 @@ \rSec2[list.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{list}}% -\indexlibrary{\idxhdr{list}}% +\indexhdr{list}% \begin{codeblock} #include namespace std { // \ref{list}, class template \tcode{list} - template > class list; + template> class list; - template + template bool operator==(const list& x, const list& y); - template + template bool operator< (const list& x, const list& y); - template + template bool operator!=(const list& x, const list& y); - template + template bool operator> (const list& x, const list& y); - template + template bool operator>=(const list& x, const list& y); - template + template bool operator<=(const list& x, const list& y); - template + template void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template + template using list = std::list>; } } @@ -3075,42 +3073,41 @@ \rSec2[vector.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{vector}}% -\indexlibrary{\idxhdr{vector}}% +\indexhdr{vector}% \begin{codeblock} #include namespace std { // \ref{vector}, class template \tcode{vector} - template > class vector; + template> class vector; - template + template bool operator==(const vector& x, const vector& y); - template + template bool operator< (const vector& x, const vector& y); - template + template bool operator!=(const vector& x, const vector& y); - template + template bool operator> (const vector& x, const vector& y); - template + template bool operator>=(const vector& x, const vector& y); - template + template bool operator<=(const vector& x, const vector& y); - template + template void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); // \ref{vector.bool}, class \tcode{vector} - template class vector; + template class vector; // hash support - template struct hash; - template struct hash>; + template struct hash; + template struct hash>; namespace pmr { - template + template using vector = std::vector>; } } @@ -3155,9 +3152,9 @@ \indexlibrarymember{array}{max_size}% \begin{codeblock} namespace std { - template + template struct array { - // types: + // types using value_type = T; using pointer = T*; using const_pointer = const T*; @@ -3175,7 +3172,7 @@ void fill(const T& u); void swap(array&) noexcept(is_nothrow_swappable_v); - // iterators: + // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; @@ -3191,12 +3188,12 @@ constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; - // capacity: - constexpr bool empty() const noexcept; + // capacity + [[nodiscard]] constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; - // element access: + // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); @@ -3238,38 +3235,17 @@ \requires \tcode{(is_same_v \&\& ...)} is \tcode{true}. Otherwise the program is ill-formed. \end{itemdescr} -\rSec3[array.special]{\tcode{array} specialized algorithms} - -\indexlibrarymember{array}{swap}% -\begin{itemdecl} -template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); -\end{itemdecl} - -\begin{itemdescr} -\pnum\remarks -This function shall not participate in overload resolution -unless \tcode{N == 0} or \tcode{is_swappable_v} is \tcode{true}. - -\pnum\effects -As if by \tcode{x.swap(y)}. - -\pnum -\complexity Linear in \tcode{N}. -\end{itemdescr} - -\rSec3[array.size]{\tcode{array::size}} +\rSec3[array.members]{\tcode{array} member functions} \indexlibrarymember{array}{size}% \begin{itemdecl} -template constexpr size_type array::size() const noexcept; +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum\returns \tcode{N}. \end{itemdescr} -\rSec3[array.data]{\tcode{array::data}} \indexlibrarymember{array}{data}% \begin{itemdecl} constexpr T* data() noexcept; @@ -3282,8 +3258,6 @@ and \range{data()}{data() + size()} is a valid range. \end{itemdescr} -\rSec3[array.fill]{\tcode{array::fill}} - \indexlibrarymember{array}{fill}% \begin{itemdecl} void fill(const T& u); @@ -3294,8 +3268,6 @@ \effects As if by \tcode{fill_n(begin(), N, u)}. \end{itemdescr} -\rSec3[array.swap]{\tcode{array::swap}} - \indexlibrarymember{array}{swap}% \begin{itemdecl} void swap(array& y) noexcept(is_nothrow_swappable_v); @@ -3313,6 +3285,26 @@ \end{note} \end{itemdescr} +\rSec3[array.special]{\tcode{array} specialized algorithms} + +\indexlibrarymember{array}{swap}% +\begin{itemdecl} +template + void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); +\end{itemdecl} + +\begin{itemdescr} +\pnum\remarks +This function shall not participate in overload resolution +unless \tcode{N == 0} or \tcode{is_swappable_v} is \tcode{true}. + +\pnum\effects +As if by \tcode{x.swap(y)}. + +\pnum +\complexity Linear in \tcode{N}. +\end{itemdescr} + \rSec3[array.zero]{Zero sized arrays} \indextext{\idxcode{array}!zero sized}% @@ -3335,7 +3327,7 @@ \indextext{\idxcode{array}!tuple interface to}% \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} -template +template struct tuple_size> : integral_constant { }; \end{itemdecl} @@ -3354,13 +3346,13 @@ \indexlibrarymember{array}{get}% \begin{itemdecl} -template +template constexpr T& get(array& a) noexcept; -template +template constexpr T&& get(array&& a) noexcept; -template +template constexpr const T& get(const array& a) noexcept; -template +template constexpr const T&& get(const array&& a) noexcept; \end{itemdecl} @@ -3400,10 +3392,10 @@ \begin{codeblock} namespace std { - template > + template> class deque { public: - // types: + // types using value_type = T; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; @@ -3422,7 +3414,7 @@ explicit deque(const Allocator&); explicit deque(size_type n, const Allocator& = Allocator()); deque(size_type n, const T& value, const Allocator& = Allocator()); - template + template deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); deque(const deque& x); deque(deque&&); @@ -3435,13 +3427,13 @@ deque& operator=(deque&& x) noexcept(allocator_traits::is_always_equal::value); deque& operator=(initializer_list); - template + template void assign(InputIterator first, InputIterator last); void assign(size_type n, const T& t); void assign(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -3457,14 +3449,14 @@ const_reverse_iterator crend() const noexcept; // \ref{deque.capacity}, capacity - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; void resize(size_type sz); void resize(size_type sz, const T& c); void shrink_to_fit(); - // element access: + // element access reference operator[](size_type n); const_reference operator[](size_type n) const; reference at(size_type n); @@ -3475,9 +3467,9 @@ const_reference back() const; // \ref{deque.modifiers}, modifiers - template reference emplace_front(Args&&... args); - template reference emplace_back(Args&&... args); - template iterator emplace(const_iterator position, Args&&... args); + template reference emplace_front(Args&&... args); + template reference emplace_back(Args&&... args); + template iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); @@ -3487,7 +3479,7 @@ iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); - template + template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list); @@ -3507,7 +3499,7 @@ -> deque::value_type, Allocator>; // \ref{deque.special}, specialized algorithms - template + template void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); } @@ -3572,7 +3564,7 @@ \indexlibrary{\idxcode{deque}!constructor}% \begin{itemdecl} -template +template deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} @@ -3657,14 +3649,14 @@ iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); -template +template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list); -template reference emplace_front(Args&&... args); -template reference emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); +template reference emplace_front(Args&&... args); +template reference emplace_back(Args&&... args); +template iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); @@ -3729,8 +3721,7 @@ \pnum \throws -Nothing unless an exception is thrown by the copy constructor, move constructor, -assignment operator, or move assignment operator of +Nothing unless an exception is thrown by the assignment operator of \tcode{T}. \end{itemdescr} @@ -3738,7 +3729,7 @@ \indexlibrarymember{swap}{deque}% \begin{itemdecl} -template +template void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -3782,10 +3773,10 @@ \begin{codeblock} namespace std { - template > + template> class forward_list { public: - // types: + // types using value_type = T; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; @@ -3802,7 +3793,7 @@ explicit forward_list(const Allocator&); explicit forward_list(size_type n, const Allocator& = Allocator()); forward_list(size_type n, const T& value, const Allocator& = Allocator()); - template + template forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); forward_list(const forward_list& x); forward_list(forward_list&& x); @@ -3814,7 +3805,7 @@ forward_list& operator=(forward_list&& x) noexcept(allocator_traits::is_always_equal::value); forward_list& operator=(initializer_list); - template + template void assign(InputIterator first, InputIterator last); void assign(size_type n, const T& t); void assign(initializer_list); @@ -3832,8 +3823,8 @@ const_iterator cbefore_begin() const noexcept; const_iterator cend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type max_size() const noexcept; // \ref{forwardlist.access}, element access @@ -3841,17 +3832,17 @@ const_reference front() const; // \ref{forwardlist.modifiers}, modifiers - template reference emplace_front(Args&&... args); + template reference emplace_front(Args&&... args); void push_front(const T& x); void push_front(T&& x); void pop_front(); - template iterator emplace_after(const_iterator position, Args&&... args); + template iterator emplace_after(const_iterator position, Args&&... args); iterator insert_after(const_iterator position, const T& x); iterator insert_after(const_iterator position, T&& x); iterator insert_after(const_iterator position, size_type n, const T& x); - template + template iterator insert_after(const_iterator position, InputIterator first, InputIterator last); iterator insert_after(const_iterator position, initializer_list il); @@ -3875,18 +3866,18 @@ const_iterator first, const_iterator last); void remove(const T& value); - template void remove_if(Predicate pred); + template void remove_if(Predicate pred); void unique(); - template void unique(BinaryPredicate binary_pred); + template void unique(BinaryPredicate binary_pred); void merge(forward_list& x); void merge(forward_list&& x); - template void merge(forward_list& x, Compare comp); - template void merge(forward_list&& x, Compare comp); + template void merge(forward_list& x, Compare comp); + template void merge(forward_list&& x, Compare comp); void sort(); - template void sort(Compare comp); + template void sort(Compare comp); void reverse() noexcept; }; @@ -3897,7 +3888,7 @@ -> forward_list::value_type, Allocator>; // \ref{forwardlist.spec}, specialized algorithms - template + template void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); } @@ -3960,7 +3951,7 @@ \indexlibrary{\idxcode{forward_list}!constructor}% \begin{itemdecl} -template +template forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} @@ -4022,7 +4013,7 @@ \indexlibrarymember{emplace_front}{forward_list}% \begin{itemdecl} -template reference emplace_front(Args&&... args); +template reference emplace_front(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4091,7 +4082,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -template +template iterator insert_after(const_iterator position, InputIterator first, InputIterator last); \end{itemdecl} @@ -4126,7 +4117,7 @@ \indexlibrarymember{emplace_after}{forward_list}% \begin{itemdecl} -template +template iterator emplace_after(const_iterator position, Args&&... args); \end{itemdecl} @@ -4227,6 +4218,14 @@ \rSec3[forwardlist.ops]{\tcode{forward_list} operations} +\pnum +In this subclause, +arguments for a template parameter +named \tcode{Predicate} or \tcode{BinaryPredicate} +shall meet the corresponding requirements in \ref{algorithms.requirements}. +For \tcode{merge} and \tcode{sort}, +the definitions and requirements in \ref{alg.sorting} apply. + \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} void splice_after(const_iterator position, forward_list& x); @@ -4313,7 +4312,7 @@ \indexlibrarymember{remove_if}{forward_list}% \begin{itemdecl} void remove(const T& value); -template void remove_if(Predicate pred); +template void remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -4338,7 +4337,7 @@ \indexlibrarymember{unique}{forward_list}% \begin{itemdecl} void unique(); -template void unique(BinaryPredicate pred); +template void unique(BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} @@ -4360,15 +4359,16 @@ \begin{itemdecl} void merge(forward_list& x); void merge(forward_list&& x); -template void merge(forward_list& x, Compare comp); -template void merge(forward_list&& x, Compare comp); +template void merge(forward_list& x, Compare comp); +template void merge(forward_list&& x, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{comp} defines a strict weak ordering\iref{alg.sorting}, and \tcode{*this} -and \tcode{x} are both sorted according to this ordering. -\tcode{get_allocator() == x.get_allocator()}. +\requires \tcode{*this} and \tcode{x} are both sorted with respect to +the comparator \tcode{operator<} (for the first two overloads) or +\tcode{comp} (for the last two overloads), and +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. \pnum \effects Merges the two sorted ranges \tcode{[begin(), end())} and @@ -4391,14 +4391,10 @@ \indexlibrarymember{sort}{forward_list}% \begin{itemdecl} void sort(); -template void sort(Compare comp); +template void sort(Compare comp); \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{operator<} (for the version with no arguments) or \tcode{comp} (for the -version with a comparison argument) defines a strict weak ordering\iref{alg.sorting}. - \pnum \effects Sorts the list according to the \tcode{operator<} or the \tcode{comp} function object. If an exception is thrown, the order of the elements in \tcode{*this} is unspecified. @@ -4429,7 +4425,7 @@ \indexlibrarymember{swap}{forward_list}% \begin{itemdecl} -template +template void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -4476,10 +4472,10 @@ \begin{codeblock} namespace std { - template > + template> class list { public: - // types: + // types using value_type = T; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; @@ -4498,7 +4494,7 @@ explicit list(const Allocator&); explicit list(size_type n, const Allocator& = Allocator()); list(size_type n, const T& value, const Allocator& = Allocator()); - template + template list(InputIterator first, InputIterator last, const Allocator& = Allocator()); list(const list& x); list(list&& x); @@ -4510,13 +4506,13 @@ list& operator=(list&& x) noexcept(allocator_traits::is_always_equal::value); list& operator=(initializer_list); - template + template void assign(InputIterator first, InputIterator last); void assign(size_type n, const T& t); void assign(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -4532,21 +4528,21 @@ const_reverse_iterator crend() const noexcept; // \ref{list.capacity}, capacity - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; void resize(size_type sz); void resize(size_type sz, const T& c); - // element access: + // element access reference front(); const_reference front() const; reference back(); const_reference back() const; // \ref{list.modifiers}, modifiers - template reference emplace_front(Args&&... args); - template reference emplace_back(Args&&... args); + template reference emplace_front(Args&&... args); + template reference emplace_back(Args&&... args); void push_front(const T& x); void push_front(T&& x); void pop_front(); @@ -4554,11 +4550,11 @@ void push_back(T&& x); void pop_back(); - template iterator emplace(const_iterator position, Args&&... args); + template iterator emplace(const_iterator position, Args&&... args); iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); - template + template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list il); @@ -4576,19 +4572,19 @@ void splice(const_iterator position, list&& x, const_iterator first, const_iterator last); void remove(const T& value); - template void remove_if(Predicate pred); + template void remove_if(Predicate pred); void unique(); - template + template void unique(BinaryPredicate binary_pred); void merge(list& x); void merge(list&& x); - template void merge(list& x, Compare comp); - template void merge(list&& x, Compare comp); + template void merge(list& x, Compare comp); + template void merge(list&& x, Compare comp); void sort(); - template void sort(Compare comp); + template void sort(Compare comp); void reverse() noexcept; }; @@ -4599,7 +4595,7 @@ -> list::value_type, Allocator>; // \ref{list.special}, specialized algorithms - template + template void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); } @@ -4675,7 +4671,7 @@ \indexlibrary{\idxcode{list}!constructor}% \begin{itemdecl} -template +template list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} @@ -4752,14 +4748,14 @@ iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); -template +template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list); -template reference emplace_front(Args&&... args); -template reference emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); +template reference emplace_front(Args&&... args); +template reference emplace_back(Args&&... args); +template iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); @@ -4817,6 +4813,12 @@ operations are provided specifically for them.\footnote{As specified in~\ref{allocator.requirements}, the requirements in this Clause apply only to lists whose allocators compare equal.} +In this subclause, +arguments for a template parameter +named \tcode{Predicate} or \tcode{BinaryPredicate} +shall meet the corresponding requirements in \ref{algorithms.requirements}. +For \tcode{merge} and \tcode{sort}, +the definitions and requirements in \ref{alg.sorting} apply. \pnum \tcode{list} provides three splice operations that destructively move elements from one list to @@ -4958,7 +4960,7 @@ \indexlibrary{\idxcode{remove}!\idxcode{list}}% \begin{itemdecl} void remove(const T& value); -template void remove_if(Predicate pred); +template void remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -4988,7 +4990,7 @@ \indexlibrary{\idxcode{unique}!\idxcode{list}}% \begin{itemdecl} void unique(); -template void unique(BinaryPredicate binary_pred); +template void unique(BinaryPredicate binary_pred); \end{itemdecl} \begin{itemdescr} @@ -5022,15 +5024,17 @@ \begin{itemdecl} void merge(list& x); void merge(list&& x); -template void merge(list& x, Compare comp); -template void merge(list&& x, Compare comp); +template void merge(list& x, Compare comp); +template void merge(list&& x, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{comp} shall define a strict weak ordering\iref{alg.sorting}, and both the list and the argument list shall be -sorted according to this ordering. +Both the list and the argument list +shall be sorted with respect to +the comparator \tcode{operator<} (for the first two overloads) or +\tcode{comp} (for the last two overloads). \pnum \effects @@ -5079,20 +5083,10 @@ \indexlibrary{\idxcode{sort}!\idxcode{list}}% \begin{itemdecl} void sort(); -template void sort(Compare comp); +template void sort(Compare comp); \end{itemdecl} \begin{itemdescr} -\pnum -\requires -\tcode{operator<} -(for the first -version) -or -\tcode{comp} -(for the second version) -shall define a strict weak ordering\iref{alg.sorting}. - \pnum \effects Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. @@ -5115,7 +5109,7 @@ \indexlibrarymember{swap}{list}% \begin{itemdecl} -template +template void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -5156,10 +5150,10 @@ \begin{codeblock} namespace std { - template > + template> class vector { public: - // types: + // types using value_type = T; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; @@ -5178,7 +5172,7 @@ explicit vector(const Allocator&) noexcept; explicit vector(size_type n, const Allocator& = Allocator()); vector(size_type n, const T& value, const Allocator& = Allocator()); - template + template vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); vector(const vector& x); vector(vector&&) noexcept; @@ -5191,13 +5185,13 @@ noexcept(allocator_traits::propagate_on_container_move_assignment::value || allocator_traits::is_always_equal::value); vector& operator=(initializer_list); - template + template void assign(InputIterator first, InputIterator last); void assign(size_type n, const T& u); void assign(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -5213,7 +5207,7 @@ const_reverse_iterator crend() const noexcept; // \ref{vector.capacity}, capacity - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; size_type capacity() const noexcept; @@ -5222,7 +5216,7 @@ void reserve(size_type n); void shrink_to_fit(); - // element access: + // element access reference operator[](size_type n); const_reference operator[](size_type n) const; const_reference at(size_type n) const; @@ -5237,16 +5231,16 @@ const T* data() const noexcept; // \ref{vector.modifiers}, modifiers - template reference emplace_back(Args&&... args); + template reference emplace_back(Args&&... args); void push_back(const T& x); void push_back(T&& x); void pop_back(); - template iterator emplace(const_iterator position, Args&&... args); + template iterator emplace(const_iterator position, Args&&... args); iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); - template + template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list il); iterator erase(const_iterator position); @@ -5263,7 +5257,7 @@ -> vector::value_type, Allocator>; // \ref{vector.special}, specialized algorithms - template + template void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); } @@ -5332,7 +5326,7 @@ \indexlibrary{\idxcode{vector}!constructor} \begin{itemdecl} -template +template vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} @@ -5542,12 +5536,12 @@ iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); -template +template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list); -template reference emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); +template reference emplace_back(Args&&... args); +template iterator emplace(const_iterator position, Args&&... args); void push_back(const T& x); void push_back(T&& x); \end{itemdecl} @@ -5606,7 +5600,7 @@ \indexlibrarymember{swap}{vector}% \begin{itemdecl} -template +template void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -5627,10 +5621,10 @@ \begin{codeblock} namespace std { - template + template class vector { public: - // types: + // types using value_type = bool; using allocator_type = Allocator; using pointer = @\impdef@; @@ -5643,7 +5637,7 @@ using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - // bit reference: + // bit reference class reference { friend class vector; reference() noexcept; @@ -5655,29 +5649,29 @@ void flip() noexcept; // flips the bit }; - // construct/copy/destroy: + // construct/copy/destroy vector() : vector(Allocator()) { } explicit vector(const Allocator&); explicit vector(size_type n, const Allocator& = Allocator()); vector(size_type n, const bool& value, const Allocator& = Allocator()); - template + template vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); - vector(const vector& x); - vector(vector&& x); + vector(const vector& x); + vector(vector&& x); vector(const vector&, const Allocator&); vector(vector&&, const Allocator&); vector(initializer_list, const Allocator& = Allocator())); ~vector(); - vector& operator=(const vector& x); - vector& operator=(vector&& x); + vector& operator=(const vector& x); + vector& operator=(vector&& x); vector& operator=(initializer_list); - template + template void assign(InputIterator first, InputIterator last); void assign(size_type n, const bool& t); void assign(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -5692,8 +5686,8 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; size_type capacity() const noexcept; @@ -5701,7 +5695,7 @@ void reserve(size_type n); void shrink_to_fit(); - // element access: + // element access reference operator[](size_type n); const_reference operator[](size_type n) const; const_reference at(size_type n) const; @@ -5711,20 +5705,20 @@ reference back(); const_reference back() const; - // modifiers: - template reference emplace_back(Args&&... args); + // modifiers + template reference emplace_back(Args&&... args); void push_back(const bool& x); void pop_back(); - template iterator emplace(const_iterator position, Args&&... args); + template iterator emplace(const_iterator position, Args&&... args); iterator insert(const_iterator position, const bool& x); iterator insert(const_iterator position, size_type n, const bool& x); - template + template iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list il); iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); - void swap(vector&); + void swap(vector&); static void swap(reference x, reference y) noexcept; void flip() noexcept; // flips all bits void clear() noexcept; @@ -5781,7 +5775,7 @@ \end{itemdescr} \begin{itemdecl} -template struct hash>; +template struct hash>; \end{itemdecl} \begin{itemdescr} @@ -5816,76 +5810,75 @@ \rSec2[associative.map.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{map}}% -\indexlibrary{\idxhdr{map}}% +\indexhdr{map}% \begin{codeblock} #include namespace std { // \ref{map}, class template \tcode{map} - template , - class Allocator = allocator>> + template, + class Allocator = allocator>> class map; - template + template bool operator==(const map& x, const map& y); - template + template bool operator< (const map& x, const map& y); - template + template bool operator!=(const map& x, const map& y); - template + template bool operator> (const map& x, const map& y); - template + template bool operator>=(const map& x, const map& y); - template + template bool operator<=(const map& x, const map& y); - template + template void swap(map& x, map& y) noexcept(noexcept(x.swap(y))); // \ref{multimap}, class template \tcode{multimap} - template , - class Allocator = allocator>> + template, + class Allocator = allocator>> class multimap; - template + template bool operator==(const multimap& x, const multimap& y); - template + template bool operator< (const multimap& x, const multimap& y); - template + template bool operator!=(const multimap& x, const multimap& y); - template + template bool operator> (const multimap& x, const multimap& y); - template + template bool operator>=(const multimap& x, const multimap& y); - template + template bool operator<=(const multimap& x, const multimap& y); - template + template void swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template > + template> using map = std::map>>; - template > + template> using multimap = std::multimap>>; } @@ -5894,74 +5887,73 @@ \rSec2[associative.set.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{set}}% -\indexlibrary{\idxhdr{set}}% +\indexhdr{set}% \begin{codeblock} #include namespace std { // \ref{set}, class template \tcode{set} - template , class Allocator = allocator> + template, class Allocator = allocator> class set; - template + template bool operator==(const set& x, const set& y); - template + template bool operator< (const set& x, const set& y); - template + template bool operator!=(const set& x, const set& y); - template + template bool operator> (const set& x, const set& y); - template + template bool operator>=(const set& x, const set& y); - template + template bool operator<=(const set& x, const set& y); - template + template void swap(set& x, set& y) noexcept(noexcept(x.swap(y))); // \ref{multiset}, class template \tcode{multiset} - template , class Allocator = allocator> + template, class Allocator = allocator> class multiset; - template + template bool operator==(const multiset& x, const multiset& y); - template + template bool operator< (const multiset& x, const multiset& y); - template + template bool operator!=(const multiset& x, const multiset& y); - template + template bool operator> (const multiset& x, const multiset& y); - template + template bool operator>=(const multiset& x, const multiset& y); - template + template bool operator<=(const multiset& x, const multiset& y); - template + template void swap(multiset& x, multiset& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template > + template> using set = std::set>; - template > + template> using multiset = std::multiset>; } } @@ -6012,11 +6004,11 @@ \begin{codeblock} namespace std { - template , - class Allocator = allocator>> + template, + class Allocator = allocator>> class map { public: - // types: + // types using key_type = Key; using mapped_type = T; using value_type = pair; @@ -6049,7 +6041,7 @@ // \ref{map.cons}, construct/copy/destroy map() : map(Compare()) { } explicit map(const Compare& comp, const Allocator& = Allocator()); - template + template map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); map(const map& x); @@ -6060,7 +6052,7 @@ map(initializer_list, const Compare& = Compare(), const Allocator& = Allocator()); - template + template map(InputIterator first, InputIterator last, const Allocator& a) : map(first, last, Compare(), a) { } map(initializer_list il, const Allocator& a) @@ -6073,7 +6065,7 @@ map& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -6089,8 +6081,8 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -6101,16 +6093,16 @@ const T& at(const key_type& x) const; // \ref{map.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + template pair emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& x); pair insert(value_type&& x); - template pair insert(P&& x); + template pair insert(P&& x); iterator insert(const_iterator position, const value_type& x); iterator insert(const_iterator position, value_type&& x); - template + template iterator insert(const_iterator position, P&&); - template + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); @@ -6119,21 +6111,21 @@ insert_return_type insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - template + template pair try_emplace(const key_type& k, Args&&... args); - template + template pair try_emplace(key_type&& k, Args&&... args); - template + template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); - template + template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); - template + template pair insert_or_assign(const key_type& k, M&& obj); - template + template pair insert_or_assign(key_type&& k, M&& obj); - template + template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); - template + template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); iterator erase(iterator position); @@ -6154,34 +6146,34 @@ template void merge(multimap&& source); - // observers: + // observers key_compare key_comp() const; value_compare value_comp() const; - // map operations: + // map operations iterator find(const key_type& x); const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; size_type count(const key_type& x) const; - template size_type count(const K& x) const; + template size_type count(const K& x) const; iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; iterator upper_bound(const key_type& x); const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; pair equal_range(const key_type& x); pair equal_range(const key_type& x) const; - template + template pair equal_range(const K& x); - template + template pair equal_range(const K& x) const; }; @@ -6195,7 +6187,7 @@ map(initializer_list>, Compare = Compare(), Allocator = Allocator()) -> map; - template + template map(InputIterator, InputIterator, Allocator) -> map, iter_val_t, less>, Allocator>; @@ -6204,7 +6196,7 @@ map(initializer_list>, Allocator) -> map, Allocator>; // \ref{map.special}, specialized algorithms - template + template void swap(map& x, map& y) noexcept(noexcept(x.swap(y))); @@ -6235,7 +6227,7 @@ \indexlibrary{\idxcode{map}!constructor}% \begin{itemdecl} -template +template map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} @@ -6306,9 +6298,9 @@ \indexlibrarymember{insert}{map}% \begin{itemdecl} -template +template pair insert(P&& x); -template +template iterator insert(const_iterator position, P&& x); \end{itemdecl} @@ -6328,9 +6320,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} -template +template pair try_emplace(const key_type& k, Args&&... args); -template +template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} @@ -6366,9 +6358,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} -template +template pair try_emplace(key_type&& k, Args&&... args); -template +template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} @@ -6404,9 +6396,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} -template +template pair insert_or_assign(const key_type& k, M&& obj); -template +template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} @@ -6441,9 +6433,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} -template +template pair insert_or_assign(key_type&& k, M&& obj); -template +template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} @@ -6480,7 +6472,7 @@ \indexlibrarymember{swap}{map}% \begin{itemdecl} -template +template void swap(map& x, map& y) noexcept(noexcept(x.swap(y))); @@ -6544,11 +6536,11 @@ \begin{codeblock} namespace std { - template , - class Allocator = allocator>> + template, + class Allocator = allocator>> class multimap { public: - // types: + // types using key_type = Key; using mapped_type = T; using value_type = pair; @@ -6580,7 +6572,7 @@ // \ref{multimap.cons}, construct/copy/destroy multimap() : multimap(Compare()) { } explicit multimap(const Compare& comp, const Allocator& = Allocator()); - template + template multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); @@ -6592,7 +6584,7 @@ multimap(initializer_list, const Compare& = Compare(), const Allocator& = Allocator()); - template + template multimap(InputIterator first, InputIterator last, const Allocator& a) : multimap(first, last, Compare(), a) { } multimap(initializer_list il, const Allocator& a) @@ -6605,7 +6597,7 @@ multimap& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -6621,21 +6613,21 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; // \ref{multimap.modifiers}, modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + template iterator emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& x); iterator insert(value_type&& x); - template iterator insert(P&& x); + template iterator insert(P&& x); iterator insert(const_iterator position, const value_type& x); iterator insert(const_iterator position, value_type&& x); - template iterator insert(const_iterator position, P&& x); - template + template iterator insert(const_iterator position, P&& x); + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); @@ -6662,34 +6654,34 @@ template void merge(map&& source); - // observers: + // observers key_compare key_comp() const; value_compare value_comp() const; - // map operations: + // map operations iterator find(const key_type& x); const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; size_type count(const key_type& x) const; - template size_type count(const K& x) const; + template size_type count(const K& x) const; iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; iterator upper_bound(const key_type& x); const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; pair equal_range(const key_type& x); pair equal_range(const key_type& x) const; - template + template pair equal_range(const K& x); - template + template pair equal_range(const K& x) const; }; @@ -6713,7 +6705,7 @@ -> multimap, Allocator>; // \ref{multimap.special}, specialized algorithms - template + template void swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); @@ -6743,7 +6735,7 @@ \indexlibrary{\idxcode{multimap}!constructor}% \begin{itemdecl} -template +template multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); @@ -6772,8 +6764,8 @@ \indexlibrarymember{insert}{multimap}% \begin{itemdecl} -template iterator insert(P&& x); -template iterator insert(const_iterator position, P&& x); +template iterator insert(P&& x); +template iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -6794,7 +6786,7 @@ \indexlibrarymember{swap}{multimap}% \begin{itemdecl} -template +template void swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); @@ -6852,11 +6844,11 @@ \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class set { public: - // types: + // types using key_type = Key; using key_compare = Compare; using value_type = Key; @@ -6878,7 +6870,7 @@ // \ref{set.cons}, construct/copy/destroy set() : set(Compare()) { } explicit set(const Compare& comp, const Allocator& = Allocator()); - template + template set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); set(const set& x); @@ -6888,7 +6880,7 @@ set(set&&, const Allocator&); set(initializer_list, const Compare& = Compare(), const Allocator& = Allocator()); - template + template set(InputIterator first, InputIterator last, const Allocator& a) : set(first, last, Compare(), a) { } set(initializer_list il, const Allocator& a) @@ -6901,7 +6893,7 @@ set& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -6917,19 +6909,19 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; - // modifiers: - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + // modifiers + template pair emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& x); pair insert(value_type&& x); iterator insert(const_iterator position, const value_type& x); iterator insert(const_iterator position, value_type&& x); - template + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); @@ -6956,34 +6948,34 @@ template void merge(multiset&& source); - // observers: + // observers key_compare key_comp() const; value_compare value_comp() const; - // set operations: + // set operations iterator find(const key_type& x); const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; size_type count(const key_type& x) const; - template size_type count(const K& x) const; + template size_type count(const K& x) const; iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; iterator upper_bound(const key_type& x); const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; pair equal_range(const key_type& x); pair equal_range(const key_type& x) const; - template + template pair equal_range(const K& x); - template + template pair equal_range(const K& x) const; }; @@ -7007,7 +6999,7 @@ set(initializer_list, Allocator) -> set, Allocator>; // \ref{set.special}, specialized algorithms - template + template void swap(set& x, set& y) noexcept(noexcept(x.swap(y))); @@ -7035,7 +7027,7 @@ \indexlibrary{\idxcode{set}!constructor}% \begin{itemdecl} -template +template set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} @@ -7063,7 +7055,7 @@ \indexlibrarymember{swap}{set}% \begin{itemdecl} -template +template void swap(set& x, set& y) noexcept(noexcept(x.swap(y))); @@ -7120,11 +7112,11 @@ \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class multiset { public: - // types: + // types using key_type = Key; using key_compare = Compare; using value_type = Key; @@ -7145,7 +7137,7 @@ // \ref{multiset.cons}, construct/copy/destroy multiset() : multiset(Compare()) { } explicit multiset(const Compare& comp, const Allocator& = Allocator()); - template + template multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); multiset(const multiset& x); @@ -7155,7 +7147,7 @@ multiset(multiset&&, const Allocator&); multiset(initializer_list, const Compare& = Compare(), const Allocator& = Allocator()); - template + template multiset(InputIterator first, InputIterator last, const Allocator& a) : multiset(first, last, Compare(), a) { } multiset(initializer_list il, const Allocator& a) @@ -7168,7 +7160,7 @@ multiset& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -7184,19 +7176,19 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; - // modifiers: - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + // modifiers + template iterator emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& x); iterator insert(value_type&& x); iterator insert(const_iterator position, const value_type& x); iterator insert(const_iterator position, value_type&& x); - template + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); @@ -7223,34 +7215,34 @@ template void merge(set&& source); - // observers: + // observers key_compare key_comp() const; value_compare value_comp() const; - // set operations: + // set operations iterator find(const key_type& x); const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; size_type count(const key_type& x) const; - template size_type count(const K& x) const; + template size_type count(const K& x) const; iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; iterator upper_bound(const key_type& x); const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; pair equal_range(const key_type& x); pair equal_range(const key_type& x) const; - template + template pair equal_range(const K& x); - template + template pair equal_range(const K& x) const; }; @@ -7274,7 +7266,7 @@ multiset(initializer_list, Allocator) -> multiset, Allocator>; // \ref{multiset.special}, specialized algorithms - template + template void swap(multiset& x, multiset& y) noexcept(noexcept(x.swap(y))); @@ -7302,7 +7294,7 @@ \indexlibrary{\idxcode{multiset}!constructor}% \begin{itemdecl} -template +template multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} @@ -7330,7 +7322,7 @@ \indexlibrarymember{swap}{multiset}% \begin{itemdecl} -template +template void swap(multiset& x, multiset& y) noexcept(noexcept(x.swap(y))); @@ -7357,8 +7349,7 @@ defined in \ref{associative.general} may appear in deduction guides for unordered containers. \rSec2[unord.map.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{unordered_map}}% -\indexlibrary{\idxhdr{unordered_map}}% +\indexhdr{unordered_map}% \indexlibrary{\idxcode{unordered_map}}% \indexlibrary{\idxcode{unordered_multimap}}% \begin{codeblock} @@ -7366,57 +7357,57 @@ namespace std { // \ref{unord.map}, class template \tcode{unordered_map} - template , - class Pred = equal_to, - class Alloc = allocator>> + template, + class Pred = equal_to, + class Alloc = allocator>> class unordered_map; // \ref{unord.multimap}, class template \tcode{unordered_multimap} - template , - class Pred = equal_to, - class Alloc = allocator>> + template, + class Pred = equal_to, + class Alloc = allocator>> class unordered_multimap; - template + template bool operator==(const unordered_map& a, const unordered_map& b); - template + template bool operator!=(const unordered_map& a, const unordered_map& b); - template + template bool operator==(const unordered_multimap& a, const unordered_multimap& b); - template + template bool operator!=(const unordered_multimap& a, const unordered_multimap& b); - template + template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); - template + template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template , - class Pred = equal_to> + template, + class Pred = equal_to> using unordered_map = std::unordered_map>>; - template , - class Pred = equal_to> + template, + class Pred = equal_to> using unordered_multimap = std::unordered_multimap>>; @@ -7426,8 +7417,7 @@ \end{codeblock} \rSec2[unord.set.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{unordered_set}}% -\indexlibrary{\idxhdr{unordered_set}}% +\indexhdr{unordered_set}% \indexlibrary{\idxcode{unordered_set}}% \indexlibrary{\idxcode{unordered_multiset}}% \begin{codeblock} @@ -7435,53 +7425,53 @@ namespace std { // \ref{unord.set}, class template \tcode{unordered_set} - template , - class Pred = equal_to, - class Alloc = allocator> + template, + class Pred = equal_to, + class Alloc = allocator> class unordered_set; // \ref{unord.multiset}, class template \tcode{unordered_multiset} - template , - class Pred = equal_to, - class Alloc = allocator> + template, + class Pred = equal_to, + class Alloc = allocator> class unordered_multiset; - template + template bool operator==(const unordered_set& a, const unordered_set& b); - template + template bool operator!=(const unordered_set& a, const unordered_set& b); - template + template bool operator==(const unordered_multiset& a, const unordered_multiset& b); - template + template bool operator!=(const unordered_multiset& a, const unordered_multiset& b); - template + template void swap(unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); - template + template void swap(unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); namespace pmr { - template , - class Pred = equal_to> + template, + class Pred = equal_to> using unordered_set = std::unordered_set>; - template , - class Pred = equal_to> + template, + class Pred = equal_to> using unordered_multiset = std::unordered_multiset>; } @@ -7507,21 +7497,21 @@ An \tcode{unordered_map} satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_map} the \tcode{key type} is \tcode{Key}, the mapped type is \tcode{T}, and the value type is \tcode{pair}. \pnum -This section only describes operations on \tcode{unordered_map} that +This subclause only describes operations on \tcode{unordered_map} that are not described in one of the requirement tables, or for which there is additional semantic information. \indexlibrary{\idxcode{unordered_map}}% \begin{codeblock} namespace std { - template , - class Pred = equal_to, - class Allocator = allocator>> + template, + class Pred = equal_to, + class Allocator = allocator>> class unordered_map { public: - // types: + // types using key_type = Key; using mapped_type = T; using value_type = pair; @@ -7548,7 +7538,7 @@ const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - template + template unordered_map(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -7568,10 +7558,10 @@ : unordered_map(n, hasher(), key_equal(), a) { } unordered_map(size_type n, const hasher& hf, const allocator_type& a) : unordered_map(n, hf, key_equal(), a) { } - template + template unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_map(f, l, n, hasher(), key_equal(), a) { } - template + template unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(f, l, n, hf, key_equal(), a) { } @@ -7589,7 +7579,7 @@ unordered_map& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -7597,21 +7587,21 @@ const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; // \ref{unord.map.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + template pair emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& obj); pair insert(value_type&& obj); - template pair insert(P&& obj); + template pair insert(P&& obj); iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, value_type&& obj); - template iterator insert(const_iterator hint, P&& obj); - template void insert(InputIterator first, InputIterator last); + template iterator insert(const_iterator hint, P&& obj); + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); node_type extract(const_iterator position); @@ -7619,21 +7609,21 @@ insert_return_type insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - template + template pair try_emplace(const key_type& k, Args&&... args); - template + template pair try_emplace(key_type&& k, Args&&... args); - template + template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); - template + template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); - template + template pair insert_or_assign(const key_type& k, M&& obj); - template + template pair insert_or_assign(key_type&& k, M&& obj); - template + template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); - template + template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); iterator erase(iterator position); @@ -7655,11 +7645,11 @@ template void merge(unordered_multimap&& source); - // observers: + // observers hasher hash_function() const; key_equal key_eq() const; - // map operations: + // map operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; @@ -7672,7 +7662,7 @@ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; - // bucket interface: + // bucket interface size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; @@ -7684,7 +7674,7 @@ const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; - // hash policy: + // hash policy float load_factor() const noexcept; float max_load_factor() const noexcept; void max_load_factor(float z); @@ -7725,12 +7715,12 @@ -> unordered_map, iter_val_t, Hash, equal_to>, Allocator>; - template + template unordered_map(initializer_list>, typename @\seebelow@::size_type, Allocator) -> unordered_map, equal_to, Allocator>; - template + template unordered_map(initializer_list>, Allocator) -> unordered_map, equal_to, Allocator>; @@ -7740,7 +7730,7 @@ -> unordered_map, Allocator>; // \ref{unord.map.swap}, swap - template + template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); @@ -7777,7 +7767,7 @@ \indexlibrary{\idxcode{unordered_map}!constructor}% \begin{itemdecl} -template +template unordered_map(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -7849,7 +7839,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} -template +template pair insert(P&& obj); \end{itemdecl} @@ -7864,7 +7854,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} -template +template iterator insert(const_iterator hint, P&& obj); \end{itemdecl} @@ -7880,9 +7870,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} -template +template pair try_emplace(const key_type& k, Args&&... args); -template +template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} @@ -7918,9 +7908,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} -template +template pair try_emplace(key_type&& k, Args&&... args); -template +template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} @@ -7956,9 +7946,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} -template +template pair insert_or_assign(const key_type& k, M&& obj); -template +template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} @@ -7993,9 +7983,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} -template +template pair insert_or_assign(key_type&& k, M&& obj); -template +template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} @@ -8032,7 +8022,7 @@ \indexlibrarymember{unordered_map}{swap}% \begin{itemdecl} -template +template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); @@ -8067,21 +8057,21 @@ mapped type is \tcode{T}, and the value type is \tcode{pair}. \pnum -This section only describes operations on \tcode{unordered_multimap} +This subclause only describes operations on \tcode{unordered_multimap} that are not described in one of the requirement tables, or for which there is additional semantic information. \indexlibrary{\idxcode{unordered_multimap}}% \begin{codeblock} namespace std { - template , - class Pred = equal_to, - class Allocator = allocator>> + template, + class Pred = equal_to, + class Allocator = allocator>> class unordered_multimap { public: - // types: + // types using key_type = Key; using mapped_type = T; using value_type = pair; @@ -8107,7 +8097,7 @@ const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - template + template unordered_multimap(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8127,10 +8117,10 @@ : unordered_multimap(n, hasher(), key_equal(), a) { } unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(n, hf, key_equal(), a) { } - template + template unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_multimap(f, l, n, hasher(), key_equal(), a) { } - template + template unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(f, l, n, hf, key_equal(), a) { } @@ -8148,7 +8138,7 @@ unordered_multimap& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -8156,21 +8146,21 @@ const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; // \ref{unord.multimap.modifiers}, modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + template iterator emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& obj); iterator insert(value_type&& obj); - template iterator insert(P&& obj); + template iterator insert(P&& obj); iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, value_type&& obj); - template iterator insert(const_iterator hint, P&& obj); - template void insert(InputIterator first, InputIterator last); + template iterator insert(const_iterator hint, P&& obj); + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); node_type extract(const_iterator position); @@ -8197,18 +8187,18 @@ template void merge(unordered_map&& source); - // observers: + // observers hasher hash_function() const; key_equal key_eq() const; - // map operations: + // map operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - // bucket interface: + // bucket interface size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; @@ -8263,12 +8253,12 @@ -> unordered_multimap, iter_val_t, Hash, equal_to>, Allocator>; - template + template unordered_multimap(initializer_list>, typename @\seebelow@::size_type, Allocator) -> unordered_multimap, equal_to, Allocator>; - template + template unordered_multimap(initializer_list>, Allocator) -> unordered_multimap, equal_to, Allocator>; @@ -8278,7 +8268,7 @@ -> unordered_multimap, Allocator>; // \ref{unord.multimap.swap}, swap - template + template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); @@ -8315,7 +8305,7 @@ \indexlibrary{\idxcode{unordered_multimap}!constructor}% \begin{itemdecl} -template +template unordered_multimap(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8348,7 +8338,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} -template +template iterator insert(P&& obj); \end{itemdecl} @@ -8363,7 +8353,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} -template +template iterator insert(const_iterator hint, P&& obj); \end{itemdecl} @@ -8381,7 +8371,7 @@ \indexlibrarymember{unordered_multimap}{swap}% \begin{itemdecl} -template +template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); @@ -8411,20 +8401,20 @@ An \tcode{unordered_set} satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_set} the \tcode{key type} and the value type are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. It is unspecified whether they are the same type. \pnum -This section only describes operations on \tcode{unordered_set} that +This subclause only describes operations on \tcode{unordered_set} that are not described in one of the requirement tables, or for which there is additional semantic information. \indexlibrary{\idxcode{unordered_set}}% \begin{codeblock} namespace std { - template , - class Pred = equal_to, - class Allocator = allocator> + template, + class Pred = equal_to, + class Allocator = allocator> class unordered_set { public: - // types: + // types using key_type = Key; using value_type = Key; using hasher = Hash; @@ -8450,7 +8440,7 @@ const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - template + template unordered_set(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8470,10 +8460,10 @@ : unordered_set(n, hasher(), key_equal(), a) { } unordered_set(size_type n, const hasher& hf, const allocator_type& a) : unordered_set(n, hf, key_equal(), a) { } - template + template unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_set(f, l, n, hasher(), key_equal(), a) { } - template + template unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_set(f, l, n, hf, key_equal(), a) { } @@ -8491,7 +8481,7 @@ unordered_set& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -8499,19 +8489,19 @@ const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; - // modifiers: - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + // modifiers + template pair emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& obj); pair insert(value_type&& obj); iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, value_type&& obj); - template void insert(InputIterator first, InputIterator last); + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); node_type extract(const_iterator position); @@ -8538,18 +8528,18 @@ template void merge(unordered_multiset&& source); - // observers: + // observers hasher hash_function() const; key_equal key_eq() const; - // set operations: + // set operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - // bucket interface: + // bucket interface size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; @@ -8561,7 +8551,7 @@ const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; - // hash policy: + // hash policy float load_factor() const noexcept; float max_load_factor() const noexcept; void max_load_factor(float z); @@ -8607,7 +8597,7 @@ -> unordered_set, Allocator>; // \ref{unord.set.swap}, swap - template + template void swap(unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); @@ -8616,8 +8606,8 @@ \pnum A \tcode{size_type} parameter type in an \tcode{unordered_set} deduction guide -refers to the \tcode{size_type} member type of the primary \tcode{unordered_set} -template. +refers to the \tcode{size_type} member type of +the type deduced by the deduction guide. \rSec3[unord.set.cnstr]{\tcode{unordered_set} constructors} @@ -8645,7 +8635,7 @@ \indexlibrary{\idxcode{unordered_set}!constructor}% \begin{itemdecl} -template +template unordered_set(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8678,7 +8668,7 @@ \indexlibrarymember{unordered_set}{swap}% \begin{itemdecl} -template +template void swap(unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); @@ -8714,20 +8704,20 @@ constant iterator types. It is unspecified whether they are the same type. \pnum -This section only describes operations on \tcode{unordered_multiset} that +This subclause only describes operations on \tcode{unordered_multiset} that are not described in one of the requirement tables, or for which there is additional semantic information. \indexlibrary{\idxcode{unordered_multiset}}% \begin{codeblock} namespace std { - template , - class Pred = equal_to, - class Allocator = allocator> + template, + class Pred = equal_to, + class Allocator = allocator> class unordered_multiset { public: - // types: + // types using key_type = Key; using value_type = Key; using hasher = Hash; @@ -8752,7 +8742,7 @@ const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - template + template unordered_multiset(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8772,10 +8762,10 @@ : unordered_multiset(n, hasher(), key_equal(), a) { } unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(n, hf, key_equal(), a) { } - template + template unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_multiset(f, l, n, hasher(), key_equal(), a) { } - template + template unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(f, l, n, hf, key_equal(), a) { } @@ -8793,7 +8783,7 @@ unordered_multiset& operator=(initializer_list); allocator_type get_allocator() const noexcept; - // iterators: + // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; @@ -8801,19 +8791,19 @@ const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; - // capacity: - bool empty() const noexcept; + // capacity + [[nodiscard]] bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; - // modifiers: - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); + // modifiers + template iterator emplace(Args&&... args); + template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& obj); iterator insert(value_type&& obj); iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, value_type&& obj); - template void insert(InputIterator first, InputIterator last); + template void insert(InputIterator first, InputIterator last); void insert(initializer_list); node_type extract(const_iterator position); @@ -8840,18 +8830,18 @@ template void merge(unordered_set&& source); - // observers: + // observers hasher hash_function() const; key_equal key_eq() const; - // set operations: + // set operations iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - // bucket interface: + // bucket interface size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; @@ -8863,7 +8853,7 @@ const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; - // hash policy: + // hash policy float load_factor() const noexcept; float max_load_factor() const noexcept; void max_load_factor(float z); @@ -8909,7 +8899,7 @@ -> unordered_multiset, Allocator>; // \ref{unord.multiset.swap}, swap - template + template void swap(unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); @@ -8918,8 +8908,8 @@ \pnum A \tcode{size_type} parameter type in an \tcode{unordered_multiset} deduction guide -refers to the \tcode{size_type} member type of the primary \tcode{unordered_multiset} -template. +refers to the \tcode{size_type} member type of +the type deduced by the deduction guide. \rSec3[unord.multiset.cnstr]{\tcode{unordered_multiset} constructors} @@ -8947,7 +8937,7 @@ \indexlibrary{\idxcode{unordered_multiset}!constructor}% \begin{itemdecl} -template +template unordered_multiset(InputIterator f, InputIterator l, size_type n = @\seebelow@, const hasher& hf = hasher(), @@ -8979,7 +8969,7 @@ \indexlibrarymember{unordered_multiset}{swap}% \begin{itemdecl} -template +template void swap(unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); @@ -9022,63 +9012,61 @@ \end{itemize} \rSec2[queue.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{queue}}% -\indexlibrary{\idxhdr{queue}} +\indexhdr{queue}% \begin{codeblock} #include namespace std { - template > class queue; - template , - class Compare = less> + template> class queue; + template, + class Compare = less> class priority_queue; - template + template bool operator==(const queue& x, const queue& y); - template + template bool operator< (const queue& x, const queue& y); - template + template bool operator!=(const queue& x, const queue& y); - template + template bool operator> (const queue& x, const queue& y); - template + template bool operator>=(const queue& x, const queue& y); - template + template bool operator<=(const queue& x, const queue& y); - template + template void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); - template + template void swap(priority_queue& x, priority_queue& y) noexcept(noexcept(x.swap(y))); } \end{codeblock} \rSec2[stack.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{stack}}% -\indexlibrary{\idxhdr{stack}} +\indexhdr{stack}% \begin{codeblock} #include namespace std { - template > class stack; + template> class stack; - template + template bool operator==(const stack& x, const stack& y); - template + template bool operator< (const stack& x, const stack& y); - template + template bool operator!=(const stack& x, const stack& y); - template + template bool operator> (const stack& x, const stack& y); - template + template bool operator>=(const stack& x, const stack& y); - template + template bool operator<=(const stack& x, const stack& y); - template + template void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); } \end{codeblock} @@ -9105,7 +9093,7 @@ \begin{codeblock} namespace std { - template > + template> class queue { public: using value_type = typename Container::value_type; @@ -9120,13 +9108,13 @@ public: explicit queue(const Container&); explicit queue(Container&& = Container()); - template explicit queue(const Alloc&); - template queue(const Container&, const Alloc&); - template queue(Container&&, const Alloc&); - template queue(const queue&, const Alloc&); - template queue(queue&&, const Alloc&); + template explicit queue(const Alloc&); + template queue(const Container&, const Alloc&); + template queue(Container&&, const Alloc&); + template queue(const queue&, const Alloc&); + template queue(queue&&, const Alloc&); - bool empty() const { return c.empty(); } + [[nodiscard]] bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } const_reference front() const { return c.front(); } @@ -9134,7 +9122,7 @@ const_reference back() const { return c.back(); } void push(const value_type& x) { c.push_back(x); } void push(value_type&& x) { c.push_back(std::move(x)); } - template + template decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward(args)...); } void pop() { c.pop_front(); } @@ -9148,10 +9136,10 @@ template queue(Container, Allocator) -> queue; - template + template void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); - template + template struct uses_allocator, Alloc> : uses_allocator::type { }; } @@ -9184,7 +9172,7 @@ the constructors in this subclause shall not participate in overload resolution. \begin{itemdecl} -template explicit queue(const Alloc& a); +template explicit queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9193,7 +9181,7 @@ \end{itemdescr} \begin{itemdecl} -template queue(const container_type& cont, const Alloc& a); +template queue(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9203,7 +9191,7 @@ \end{itemdescr} \begin{itemdecl} -template queue(container_type&& cont, const Alloc& a); +template queue(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9213,7 +9201,7 @@ \end{itemdescr} \begin{itemdecl} -template queue(const queue& q, const Alloc& a); +template queue(const queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9223,7 +9211,7 @@ \end{itemdescr} \begin{itemdecl} -template queue(queue&& q, const Alloc& a); +template queue(queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9236,7 +9224,7 @@ \indexlibrary{\idxcode{operator==}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator==(const queue& x, const queue& y); \end{itemdecl} @@ -9248,7 +9236,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator!=(const queue& x, const queue& y); \end{itemdecl} @@ -9260,7 +9248,7 @@ \indexlibrary{\idxcode{operator<}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator< (const queue& x, const queue& y); \end{itemdecl} @@ -9272,7 +9260,7 @@ \indexlibrary{\idxcode{operator<=}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator<=(const queue& x, const queue& y); \end{itemdecl} @@ -9284,7 +9272,7 @@ \indexlibrary{\idxcode{operator>}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator> (const queue& x, const queue& y); \end{itemdecl} @@ -9296,7 +9284,7 @@ \indexlibrary{\idxcode{operator>=}!\idxcode{queue}}% \begin{itemdecl} -template +template bool operator>=(const queue& x, const queue& y); \end{itemdecl} @@ -9311,7 +9299,7 @@ \indexlibrarymember{swap}{queue}% \begin{itemdecl} -template +template void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -9349,8 +9337,8 @@ \begin{codeblock} namespace std { - template , - class Compare = less> + template, + class Compare = less> class priority_queue { public: using value_type = typename Container::value_type; @@ -9367,25 +9355,25 @@ public: priority_queue(const Compare& x, const Container&); explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); - template + template priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container&); - template + template priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(), Container&& = Container()); - template explicit priority_queue(const Alloc&); - template priority_queue(const Compare&, const Alloc&); - template priority_queue(const Compare&, const Container&, const Alloc&); - template priority_queue(const Compare&, Container&&, const Alloc&); - template priority_queue(const priority_queue&, const Alloc&); - template priority_queue(priority_queue&&, const Alloc&); - - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - const_reference top() const { return c.front(); } + template explicit priority_queue(const Alloc&); + template priority_queue(const Compare&, const Alloc&); + template priority_queue(const Compare&, const Container&, const Alloc&); + template priority_queue(const Compare&, Container&&, const Alloc&); + template priority_queue(const priority_queue&, const Alloc&); + template priority_queue(priority_queue&&, const Alloc&); + + [[nodiscard]] bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + const_reference top() const { return c.front(); } void push(const value_type& x); void push(value_type&& x); - template void emplace(Args&&... args); + template void emplace(Args&&... args); void pop(); void swap(priority_queue& q) noexcept(is_nothrow_swappable_v && is_nothrow_swappable_v) @@ -9408,11 +9396,11 @@ // no equality is provided - template + template void swap(priority_queue& x, priority_queue& y) noexcept(noexcept(x.swap(y))); - template + template struct uses_allocator, Alloc> : uses_allocator::type { }; } @@ -9444,9 +9432,9 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template +template priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y); -template +template priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(), Container&& y = Container()); \end{itemdecl} @@ -9477,7 +9465,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template explicit priority_queue(const Alloc& a); +template explicit priority_queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9487,7 +9475,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template priority_queue(const Compare& compare, const Alloc& a); +template priority_queue(const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9497,7 +9485,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template +template priority_queue(const Compare& compare, const Container& cont, const Alloc& a); \end{itemdecl} @@ -9510,7 +9498,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template +template priority_queue(const Compare& compare, Container&& cont, const Alloc& a); \end{itemdecl} @@ -9523,7 +9511,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template priority_queue(const priority_queue& q, const Alloc& a); +template priority_queue(const priority_queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9534,7 +9522,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} -template priority_queue(priority_queue&& q, const Alloc& a); +template priority_queue(priority_queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9577,7 +9565,7 @@ \indexlibrarymember{emplace}{priority_queue}% \begin{itemdecl} -template void emplace(Args&&... args) +template void emplace(Args&&... args) \end{itemdecl} \begin{itemdescr} @@ -9610,7 +9598,7 @@ \indexlibrarymember{swap}{priority_queue}% \begin{itemdecl} -template +template void swap(priority_queue& x, priority_queue& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} @@ -9648,7 +9636,7 @@ \begin{codeblock} namespace std { - template > + template> class stack { public: using value_type = typename Container::value_type; @@ -9663,19 +9651,19 @@ public: explicit stack(const Container&); explicit stack(Container&& = Container()); - template explicit stack(const Alloc&); - template stack(const Container&, const Alloc&); - template stack(Container&&, const Alloc&); - template stack(const stack&, const Alloc&); - template stack(stack&&, const Alloc&); + template explicit stack(const Alloc&); + template stack(const Container&, const Alloc&); + template stack(Container&&, const Alloc&); + template stack(const stack&, const Alloc&); + template stack(stack&&, const Alloc&); - bool empty() const { return c.empty(); } + [[nodiscard]] bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference top() { return c.back(); } const_reference top() const { return c.back(); } void push(const value_type& x) { c.push_back(x); } void push(value_type&& x) { c.push_back(std::move(x)); } - template + template decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward(args)...); } void pop() { c.pop_back(); } @@ -9689,7 +9677,7 @@ template stack(Container, Allocator) -> stack; - template + template struct uses_allocator, Alloc> : uses_allocator::type { }; } @@ -9725,7 +9713,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -template explicit stack(const Alloc& a); +template explicit stack(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9735,7 +9723,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -template stack(const container_type& cont, const Alloc& a); +template stack(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9746,7 +9734,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -template stack(container_type&& cont, const Alloc& a); +template stack(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9757,7 +9745,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -template stack(const stack& s, const Alloc& a); +template stack(const stack& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9768,7 +9756,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -template stack(stack&& s, const Alloc& a); +template stack(stack&& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -9781,7 +9769,7 @@ \indexlibrary{\idxcode{operator==}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator==(const stack& x, const stack& y); \end{itemdecl} @@ -9793,7 +9781,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator!=(const stack& x, const stack& y); \end{itemdecl} @@ -9805,7 +9793,7 @@ \indexlibrary{\idxcode{operator<}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator< (const stack& x, const stack& y); \end{itemdecl} @@ -9817,7 +9805,7 @@ \indexlibrary{\idxcode{operator<=}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator<=(const stack& x, const stack& y); \end{itemdecl} @@ -9829,7 +9817,7 @@ \indexlibrary{\idxcode{operator>}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator> (const stack& x, const stack& y); \end{itemdecl} @@ -9841,7 +9829,7 @@ \indexlibrary{\idxcode{operator>=}!\idxcode{stack}}% \begin{itemdecl} -template +template bool operator>=(const stack& x, const stack& y); \end{itemdecl} @@ -9855,7 +9843,7 @@ \indexlibrarymember{swap}{stack}% \begin{itemdecl} -template +template void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} diff --git a/source/conversions.tex b/source/conversions.tex index 23a88a9fdd..5d371bac31 100644 --- a/source/conversions.tex +++ b/source/conversions.tex @@ -3,7 +3,7 @@ \indextext{implicit conversion|see{conversion, implicit}} \indextext{contextually converted to bool|see{conversion, contextual}} -\indextext{rvalue!lvalue conversion to|see{conversion, lvalue to rvalue}}% +\indextext{rvalue!lvalue conversion to|see{conversion, lvalue-to-rvalue}}% \pnum \indextext{conversion!standard|(}% @@ -22,7 +22,7 @@ \item Zero or one conversion from the following set: integral promotions, floating-point promotion, integral conversions, floating-point conversions, floating-integral conversions, pointer conversions, -pointer to member conversions, and boolean conversions. +pointer-to-member conversions, and boolean conversions. \item Zero or one function pointer conversion. @@ -41,7 +41,7 @@ \begin{itemize} \item When used as operands of operators. The operator's requirements -for its operands dictate the destination type\iref{expr}. +for its operands dictate the destination type\iref{expr.compound}. \item When used in the condition of an \tcode{if} statement or iteration statement~(\ref{stmt.select}, \ref{stmt.iter}). The destination type is @@ -129,7 +129,7 @@ is a non-class type, the type of the prvalue is the cv-unqualified version of \tcode{T}. Otherwise, the type of the prvalue is \tcode{T}.% -\footnote{In \Cpp class and array prvalues can have cv-qualified types. +\footnote{In \Cpp{} class and array prvalues can have cv-qualified types. This differs from ISO C, in which non-lvalues never have cv-qualified types.} @@ -289,16 +289,16 @@ \begin{itemize} \item $\tcode{T}_1$ and $\tcode{T}_2$ are similar. -\item For every $i > 0$, if \tcode{const} is in $\mathit{cv}_i^1$ then \tcode{const} is in $\mathit{cv}_i^2$, and similarly for \tcode{volatile}. +\item For every $i > 0$, if \tcode{const} is in $\text{\cv}_i^1$ then \tcode{const} is in $\text{\cv}_i^2$, and similarly for \tcode{volatile}. -\item If the $\mathit{cv}_i^1$ and $\mathit{cv}_i^2$ are different, -then \tcode{const} is in every $\mathit{cv}_k^2$ for $0 < k < i$. +\item If the $\text{\cv}_i^1$ and $\text{\cv}_i^2$ are different, +then \tcode{const} is in every $\text{\cv}_k^2$ for $0 < k < i$. \end{itemize} \begin{note} If a program could assign a pointer of type \tcode{T**} to a pointer of type \tcode{const} \tcode{T**} (that is, if line \#1 below were -allowed), a program could inadvertently modify a \tcode{const} object +allowed), a program could inadvertently modify a const object (as it is done on line \#2). For example, \begin{codeblock} @@ -307,7 +307,7 @@ char* pc; const char** pcc = &pc; // \#1: not allowed *pcc = &c; - *pc = 'C'; // \#2: modifies a \tcode{const} object + *pc = 'C'; // \#2: modifies a const object } \end{codeblock} \end{note} @@ -527,21 +527,22 @@ object. The null pointer value is converted to the null pointer value of the destination type. -\rSec1[conv.mem]{Pointer to member conversions} +\rSec1[conv.mem]{Pointer-to-member conversions} \pnum -\indextext{conversion!pointer to member}% +\indextext{conversion!pointer-to-member}% \indextext{constant!null pointer}% \indextext{value!null member pointer}% -A null pointer constant\iref{conv.ptr} can be converted to a pointer -to member type; the result is the \term{null member pointer value} +A null pointer constant\iref{conv.ptr} can be converted to a +pointer-to-member +type; the result is the \term{null member pointer value} of that type and is distinguishable from any pointer to member not created from a null pointer constant. Such a conversion is called a \term{null member pointer conversion}. Two null member pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to member of cv-qualified type is a single -conversion, and not the sequence of a pointer to member conversion +conversion, and not the sequence of a pointer-to-member conversion followed by a qualification conversion\iref{conv.qual}. \pnum @@ -571,7 +572,7 @@ an object pointer or a function pointer and the rules for conversions of such pointers do not apply to pointers to members. -\indextext{conversion!pointer to member!\idxcode{void*}}% +\indextext{conversion!pointer-to-member!\idxcode{void*}}% In particular, a pointer to member cannot be converted to a \tcode{void*}.} @@ -600,7 +601,7 @@ \pnum \indextext{conversion!boolean}% -A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member +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 @@ -608,59 +609,4 @@ \tcode{std::nullptr_t} can be converted to a prvalue of type \tcode{bool}; the resulting value is \tcode{false}. -\rSec1[conv.rank]{Integer conversion rank}% -\indextext{conversion!integer rank} - -\pnum -Every integer type has an \term{integer conversion rank} defined as follows: - -\begin{itemize} -\item No two signed integer types other than \tcode{char} and \tcode{signed -char} (if \tcode{char} is signed) shall have the same rank, even if they have -the same representation. - -\item The rank of a signed integer type shall be greater than the rank -of any signed integer type with a smaller size. - -\item The rank of \tcode{long long int} shall be greater -than the rank of \tcode{long int}, which shall be greater than -the rank of \tcode{int}, which shall be greater than the rank of -\tcode{short int}, which shall be greater than the rank of -\tcode{signed char}. - -\item The rank of any unsigned integer type shall equal the rank of the -corresponding signed integer type. - -\item The rank of any standard integer type shall be greater than the -rank of any extended integer type with the same size. - -\item The rank of \tcode{char} shall equal the rank of \tcode{signed char} -and \tcode{unsigned char}. - -\item The rank of \tcode{bool} shall be less than the rank of all other -standard integer types. - -\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 -\tcode{wchar_t} shall equal the ranks of their underlying -types\iref{basic.fundamental}. - -\item The rank of any extended signed integer type relative to another -extended signed integer type with the same size is \impldef{rank of extended signed -integer type}, but still subject to the other rules for determining the integer -conversion rank. - -\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if -\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater -rank than \tcode{T3}, then \tcode{T1} shall have greater rank than -\tcode{T3}. -\end{itemize} - -\begin{note} -The integer conversion rank is used in the definition of the integral -promotions\iref{conv.prom} and the usual arithmetic -conversions\iref{expr}. -\end{note}% \indextext{conversion!standard|)} diff --git a/source/cover-reg.tex b/source/cover-reg.tex index ff05bfb99c..91e968e150 100644 --- a/source/cover-reg.tex +++ b/source/cover-reg.tex @@ -2,6 +2,11 @@ %%-------------------------------------------------- %% Title page for the C++ Standard +\setlength{\fboxsep}{1em} +\newlength{\copyboxwidth} +\setlength{\copyboxwidth}{\textwidth} +\addtolength{\copyboxwidth}{-2\fboxsep} +\addtolength{\copyboxwidth}{-2\fboxrule} \thispagestyle{empty} {\raisebox{.35ex}{\smaller\copyright}}\,ISO 2017 --- All rights reserved @@ -22,29 +27,28 @@ \vfill -\textbf{\LARGE Programming Languages --- \Cpp} +\textbf{\LARGE Programming Languages --- \Cpp{}} -Langages de programmation --- \Cpp +Langages de programmation --- \Cpp{} \vfill -\begin{tabular}{|p{\hsize}|} -\hline +\fbox{% +\begin{minipage}{\copyboxwidth} +\vspace{1ex} \begin{center} \textbf{Warning} \end{center} - \vspace{2ex} This document is not an ISO International Standard. It is distributed for review and comment. It is subject to change without notice and may -not be referred to as an International Standard.\\\\ +not be referred to as an International Standard.\\[1em] Recipients of this draft are invited to submit, with their comments, notification of any relevant patent rights of which they are aware -and to provide supporting documentation.\\\\ -\hline -\end{tabular} +and to provide supporting documentation.\\ +\end{minipage}} \vfill \noindent @@ -55,11 +59,6 @@ \thispagestyle{cpppage} -\setlength{\fboxsep}{1em} -\newlength{\copyboxwidth} -\setlength{\copyboxwidth}{\textwidth} -\addtolength{\copyboxwidth}{-2\fboxsep} -\addtolength{\copyboxwidth}{-2\fboxrule} \fbox{% \begin{minipage}{\copyboxwidth} \vspace{1ex} diff --git a/source/cover-wd.tex b/source/cover-wd.tex index d2fcdb118b..949c38dc45 100644 --- a/source/cover-wd.tex +++ b/source/cover-wd.tex @@ -22,7 +22,7 @@ \vspace{2.5cm} \begin{center} \textbf{\Huge -Working Draft, Standard for Programming Language \Cpp} +Working Draft, Standard for Programming Language \Cpp{}} \end{center} \vfill \textbf{Note: this is an early draft. It's known to be incomplet and diff --git a/source/declarations.tex b/source/declarations.tex index a7ffc30e59..d4375702ae 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -45,19 +45,19 @@ \begin{bnf} \nontermdef{nodeclspec-function-declaration}\br - attribute-specifier-seq\opt declarator \terminal{;} + \opt{attribute-specifier-seq} declarator \terminal{;} \end{bnf} \begin{bnf} \nontermdef{alias-declaration}\br - \terminal{using} identifier attribute-specifier-seq\opt{} \terminal{=} defining-type-id \terminal{;} + \terminal{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;} \end{bnf} \begin{bnf} \nontermdef{simple-declaration}\br - decl-specifier-seq init-declarator-list\opt{} \terminal{;}\br + decl-specifier-seq \opt{init-declarator-list} \terminal{;}\br attribute-specifier-seq decl-specifier-seq init-declarator-list \terminal{;}\br - attribute-specifier-seq\opt decl-specifier-seq ref-qualifier\opt{} \terminal{[} identifier-list \terminal{]} initializer \terminal{;} + \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} identifier-list \terminal{]} initializer \terminal{;} \end{bnf} \begin{bnf} @@ -93,7 +93,7 @@ \grammarterm{nodeclspec-function-declaration} of the form \begin{ncsimplebnf} -attribute-specifier-seq\opt decl-specifier-seq\opt init-declarator-list\opt{} \terminal{;} +\opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{init-declarator-list} \terminal{;} \end{ncsimplebnf} is divided into three parts. @@ -259,7 +259,7 @@ \begin{bnf} \nontermdef{decl-specifier-seq}\br - decl-specifier attribute-specifier-seq\opt\br + decl-specifier \opt{attribute-specifier-seq}\br decl-specifier decl-specifier-seq \end{bnf} @@ -486,7 +486,7 @@ The \tcode{mutable} specifier on a class data member nullifies a \tcode{const} specifier applied to the containing class object and permits modification of the mutable class member even though the rest of -the object is \tcode{const}\iref{dcl.type.cv}. +the object is const\iref{dcl.type.cv}. \rSec2[dcl.fct.spec]{Function specifiers}% \indextext{specifier!function}% @@ -694,10 +694,15 @@ \grammarterm{typedef-name} declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only\iref{basic.link}. +\begin{note} +A typedef declaration involving a \grammarterm{lambda-expression} +does not itself define the associated closure type, +and so the closure type is not given a name for linkage purposes. +\end{note} \begin{example} - \begin{codeblock} typedef struct { } *ps, S; // \tcode{S} is the class name for linkage purposes +typedef decltype([]{}) C; // the closure type has no name for linkage purposes \end{codeblock} \end{example} @@ -943,7 +948,7 @@ \pnum A \tcode{constexpr} specifier used in an object declaration -declares the object as \tcode{const}. +declares the object as const. Such an object shall have literal type and shall be initialized. @@ -977,7 +982,7 @@ point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, -the other rules for inline functions specified in this section shall +the other rules for inline functions specified in this subclause shall still be respected. \pnum @@ -1035,7 +1040,7 @@ \begin{bnf} \nontermdef{type-specifier-seq}\br - type-specifier attribute-specifier-seq\opt\br + type-specifier \opt{attribute-specifier-seq}\br type-specifier type-specifier-seq \end{bnf} @@ -1048,7 +1053,7 @@ \begin{bnf} \nontermdef{defining-type-specifier-seq}\br - defining-type-specifier attribute-specifier-seq\opt\br + defining-type-specifier \opt{attribute-specifier-seq}\br defining-type-specifier defining-type-specifier-seq \end{bnf} @@ -1110,7 +1115,7 @@ \ref{class}, and \ref{temp.res}, respectively. The remaining -\grammarterm{type-specifier}{s} are discussed in the rest of this section. +\grammarterm{type-specifier}{s} are discussed in the rest of this subclause. \end{note} \rSec3[dcl.type.cv]{The \grammarterm{cv-qualifier}{s}}% @@ -1154,9 +1159,9 @@ \end{note} \pnum -\indextext{const object@\tcode{const}-object!undefined change to}% +\indextext{const object!undefined change to}% Except that any class member declared \tcode{mutable}\iref{dcl.stc} -can be modified, any attempt to modify a \tcode{const} object during its +can be modified, any attempt to modify a const object during its lifetime\iref{basic.life} results in undefined behavior. \begin{example} \begin{codeblock} @@ -1170,11 +1175,11 @@ int* ip; ip = const_cast(cip); // cast needed to convert \tcode{const int*} to \tcode{int*} -*ip = 4; // defined: \tcode{*ip} points to \tcode{i}, a non-\tcode{const} object +*ip = 4; // defined: \tcode{*ip} points to \tcode{i}, a non-const object const int* ciq = new const int (3); // initialized as required int* iq = const_cast(ciq); // cast required -*iq = 4; // undefined: modifies a \tcode{const} object +*iq = 4; // undefined: modifies a const object \end{codeblock} For another example, \begin{codeblock} @@ -1192,7 +1197,7 @@ y.x.j++; // ill-formed: const-qualified member modified Y* p = const_cast(&y); // cast away const-ness of \tcode{y} p->x.i = 99; // well-formed: \tcode{mutable} member can be modified -p->x.j = 99; // undefined: modifies a \tcode{const} member +p->x.j = 99; // undefined: modifies a const subobject \end{codeblock} \end{example} @@ -1213,7 +1218,7 @@ Furthermore, for some implementations, \tcode{volatile} might indicate that special hardware instructions are required to access the object. See~\ref{intro.execution} for detailed semantics. In general, the -semantics of \tcode{volatile} are intended to be the same in \Cpp as +semantics of \tcode{volatile} are intended to be the same in \Cpp{} as they are in C. \end{note} @@ -1225,9 +1230,9 @@ \begin{bnf} \nontermdef{simple-type-specifier}\br - nested-name-specifier\opt type-name\br + \opt{nested-name-specifier} type-name\br nested-name-specifier \terminal{template} simple-template-id\br - nested-name-specifier\opt template-name\br + \opt{nested-name-specifier} template-name\br \terminal{char}\br \terminal{char16_t}\br \terminal{char32_t}\br @@ -1282,7 +1287,7 @@ a type to be deduced\iref{dcl.spec.auto}. \indextext{deduction!class template arguments}% A \grammarterm{type-specifier} of the form -\tcode{typename}\opt{} \grammarterm{nested-name-specifier}\opt{} \grammarterm{template-name} +\opt{\tcode{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} is a placeholder for a deduced class type\iref{dcl.type.class.deduct}. The \grammarterm{template-name} shall name a class template @@ -1384,7 +1389,7 @@ \end{itemize} The operand of the \tcode{decltype} specifier is an unevaluated -operand\iref{expr}. +operand\iref{expr.prop}. \begin{example} \begin{codeblock} @@ -1437,7 +1442,7 @@ -> void; auto g() -> void { f(42); // OK: calls \#2. (\#1 is not a viable candidate: type deduction - // fails\iref{temp.deduct} because \tcode{A::\tilde{}A()} is implicitly used in its + // fails\iref{temp.deduct} because \tcode{A::\~{}A()} is implicitly used in its // \grammarterm{decltype-specifier}) } template auto q(T) @@ -1459,10 +1464,10 @@ \begin{bnf} \nontermdef{elaborated-type-specifier}\br - class-key attribute-specifier-seq\opt nested-name-specifier\opt identifier\br + class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br class-key simple-template-id\br - class-key nested-name-specifier \terminal{template}\opt simple-template-id\br - \terminal{enum} nested-name-specifier\opt identifier + class-key nested-name-specifier \opt{\terminal{template}} simple-template-id\br + \terminal{enum} \opt{nested-name-specifier} identifier \end{bnf} \pnum @@ -1477,11 +1482,11 @@ forms: \begin{ncsimplebnf} -class-key attribute-specifier-seq\opt identifier \terminal{;}\br -\terminal{friend} class-key \terminal{::\opt} identifier \terminal{;}\br -\terminal{friend} class-key \terminal{::\opt} simple-template-id \terminal{;}\br +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{template\opt} simple-template-id \terminal{;} +\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 @@ -1519,7 +1524,7 @@ declaration to which the name in the \grammarterm{elaborated-type-specifier} refers. This rule also applies to the form of \grammarterm{elaborated-type-specifier} that declares a -\grammarterm{class-name} or \tcode{friend} class since it can be construed +\grammarterm{class-name} or friend class since it can be construed as referring to the definition of the class. Thus, in any \grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword shall be @@ -1609,7 +1614,7 @@ \pnum A program that uses \tcode{auto} or \tcode{decltype(auto)} in a context not -explicitly allowed in this section is ill-formed. +explicitly allowed in this subclause is ill-formed. \pnum If the \grammarterm{init-declarator-list} contains more than one @@ -1906,23 +1911,23 @@ \begin{bnf} \nontermdef{enum-specifier}\br - enum-head \terminal{\{} enumerator-list\opt{} \terminal{\}}\br + enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br enum-head \terminal{\{} enumerator-list \terminal{, \}} \end{bnf} \begin{bnf} \nontermdef{enum-head}\br - enum-key attribute-specifier-seq\opt enum-head-name\opt enum-base\opt + enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base} \end{bnf} \begin{bnf} \nontermdef{enum-head-name}\br - nested-name-specifier\opt identifier + \opt{nested-name-specifier} identifier \end{bnf} \begin{bnf} \nontermdef{opaque-enum-declaration}\br - enum-key attribute-specifier-seq\opt nested-name-specifier\opt identifier enum-base\opt{} \terminal{;} + enum-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier \opt{enum-base} \terminal{;} \end{bnf} \begin{bnf} @@ -1951,7 +1956,7 @@ \begin{bnf} \nontermdef{enumerator}\br - identifier attribute-specifier-seq\opt + identifier \opt{attribute-specifier-seq} \end{bnf} The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and @@ -1959,7 +1964,7 @@ in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the enumeration whenever it is named. A \tcode{:} following -``\tcode{enum} \grammarterm{nested-name-specifier}\opt{} \grammarterm{identifier}'' +``\tcode{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}'' within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration} is parsed as part of an \grammarterm{enum-base}. \begin{note} This resolves a potential ambiguity between the declaration of an enumeration @@ -2260,12 +2265,12 @@ \begin{bnf} \nontermdef{named-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt identifier \terminal{\{} namespace-body \terminal{\}} + \terminal{\opt{inline}} \terminal{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{unnamed-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt{} \terminal{\{} namespace-body \terminal{\}} + \terminal{\opt{inline}} \terminal{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} @@ -2281,7 +2286,7 @@ \begin{bnf} \nontermdef{namespace-body}\br - declaration-seq\opt + \opt{declaration-seq} \end{bnf} \pnum @@ -2418,7 +2423,7 @@ replaced by \begin{ncsimplebnf} -\terminal{inline}\opt{} \terminal{namespace} \terminal{\uniquens} \terminal{\{ /* empty body */ \}}\br +\opt{\terminal{inline}} \terminal{namespace} \terminal{\uniquens} \terminal{\{ /* empty body */ \}}\br \terminal{using namespace} \terminal{\uniquens} \terminal{;}\br \terminal{namespace} \terminal{\uniquens} \terminal{\{} namespace-body \terminal{\}} \end{ncsimplebnf} @@ -2463,7 +2468,7 @@ whose \grammarterm{class-head-name}\iref{class} or \grammarterm{enum-head-name}\iref{dcl.enum} is an \grammarterm{identifier}, or whose \grammarterm{elaborated-type-specifier} is of the form \grammarterm{class-key} -\grammarterm{attribute-specifier-seq}\opt{} \grammarterm{identifier}\iref{dcl.type.elab}, or +\opt{\grammarterm{attribute-specifier-seq}} \grammarterm{identifier}\iref{dcl.type.elab}, or that is an \grammarterm{opaque-enum-declaration}, declares (or redeclares) its \grammarterm{unqualified-id} or \grammarterm{identifier} as a member of \tcode{N}. @@ -2515,10 +2520,10 @@ \end{example} \pnum -If a \tcode{friend} declaration in a non-local class first declares a +If a friend declaration in a non-local class first declares a class, function, class template or function template\footnote{this implies that the name of the class or function is unqualified.} the friend is a member of the innermost enclosing -namespace. The \tcode{friend} declaration does not by itself make the name +namespace. The friend declaration does not by itself make the name visible to unqualified lookup\iref{basic.lookup.unqual} or qualified lookup\iref{basic.lookup.qual}. \begin{note} The name of the friend will be visible in its namespace if a matching declaration is provided at namespace @@ -2528,12 +2533,12 @@ name lookup that considers functions from namespaces and classes associated with the types of the function arguments\iref{basic.lookup.argdep}. If the -name in a \tcode{friend} declaration is neither qualified nor a +name in a friend declaration is neither qualified nor a \grammarterm{template-id} and the declaration is a function or an \grammarterm{elaborated-type-specifier}, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace. \begin{note} The other forms of -\tcode{friend} declarations cannot declare a new member of the innermost +friend declarations cannot declare a new member of the innermost enclosing namespace and thus follow the usual lookup rules. \end{note} \begin{example} @@ -2592,7 +2597,7 @@ \begin{bnf} \nontermdef{qualified-namespace-specifier}\br - nested-name-specifier\opt namespace-name + \opt{nested-name-specifier} namespace-name \end{bnf} \pnum @@ -2632,13 +2637,13 @@ \begin{bnf} \nontermdef{using-declarator-list}\br - using-declarator \terminal{...}\opt\br - using-declarator-list \terminal{,} using-declarator \terminal{...}\opt + using-declarator \opt{\terminal{...}}\br + using-declarator-list \terminal{,} using-declarator \opt{\terminal{...}} \end{bnf} \begin{bnf} \nontermdef{using-declarator}\br - \terminal{typename\opt} nested-name-specifier unqualified-id + \terminal{\opt{typename}} nested-name-specifier unqualified-id \end{bnf} \pnum @@ -3112,7 +3117,7 @@ \begin{bnf} \nontermdef{using-directive}\br - attribute-specifier-seq\opt{} \terminal{using namespace} nested-name-specifier\opt namespace-name \terminal{;} + \opt{attribute-specifier-seq} \terminal{using namespace} \opt{nested-name-specifier} namespace-name \terminal{;} \end{bnf} \pnum @@ -3328,7 +3333,7 @@ \begin{bnf} \nontermdef{asm-definition}\br - attribute-specifier-seq\opt{} \terminal{asm (} string-literal \terminal{) ;} + \opt{attribute-specifier-seq} \terminal{asm (} string-literal \terminal{) ;} \end{bnf} The \tcode{asm} declaration is conditionally-supported; its meaning is @@ -3354,12 +3359,12 @@ external linkage, or with a particular calling convention, etc. \end{note} The default language linkage of all function types, function names, and -variable names is \Cpp language linkage. Two function types with +variable names is \Cpp{} language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical. \pnum -Linkage\iref{basic.link} between \Cpp and non-\Cpp code fragments can +Linkage\iref{basic.link} between \Cpp{} and non-\Cpp{} code fragments can be achieved using a \grammarterm{linkage-specification}: \indextext{\idxgram{linkage-specification}}% @@ -3367,7 +3372,7 @@ % \begin{bnf} \nontermdef{linkage-specification}\br - \terminal{extern} string-literal \terminal{\{} declaration-seq\opt{} \terminal{\}}\br + \terminal{extern} string-literal \terminal{\{} \opt{declaration-seq} \terminal{\}}\br \terminal{extern} string-literal declaration \end{bnf} @@ -3392,10 +3397,10 @@ Every implementation shall provide for linkage to functions written in the C programming language, \indextext{C!linkage to}% -\tcode{"C"}, and linkage to \Cpp functions, \tcode{"C++"}. +\tcode{"C"}, and linkage to \Cpp{} functions, \tcode{"C++"}. \begin{example} \begin{codeblock} -complex sqrt(complex); // \Cpp linkage by default +complex sqrt(complex); // \Cpp{} linkage by default extern "C" { double sqrt(double); // C linkage } @@ -3418,13 +3423,13 @@ void f1(void(*pf)(int)); // \tcode{pf} is a pointer to a C function extern "C" typedef void FUNC(); -FUNC f2; // the name \tcode{f2} has \Cpp language linkage and the +FUNC f2; // the name \tcode{f2} has \Cpp{} language linkage and the // function's type has C language linkage extern "C" FUNC f3; // the name of function \tcode{f3} and the function's type have C language linkage -void (*pf2)(FUNC*); // the name of the variable \tcode{pf2} has \Cpp linkage and the type - // of \tcode{pf2} is ``pointer to \Cpp function that takes one parameter of type +void (*pf2)(FUNC*); // the name of the variable \tcode{pf2} has \Cpp{} linkage and the type + // of \tcode{pf2} is ``pointer to \Cpp{} function that takes one parameter of type // pointer to C function'' extern "C" { static void f4(); // the name of the function \tcode{f4} has internal linkage (not C language linkage) @@ -3456,20 +3461,20 @@ class C { void mf1(FUNC_c*); // the name of the function \tcode{mf1} and the member function's type have - // \Cpp language linkage; the parameter has type ``pointer to C function'' + // \Cpp{} language linkage; the parameter has type ``pointer to C function'' FUNC_c mf2; // the name of the function \tcode{mf2} and the member function's type have - // \Cpp language linkage + // \Cpp{} language linkage - static FUNC_c* q; // the name of the data member \tcode{q} has \Cpp language linkage and + static FUNC_c* q; // the name of the data member \tcode{q} has \Cpp{} language linkage and // the data member's type is ``pointer to C function'' }; extern "C" { class X { void mf(); // the name of the function \tcode{mf} and the member function's type have - // \Cpp language linkage - void mf2(void(*)()); // the name of the function \tcode{mf2} has \Cpp language linkage; + // \Cpp{} language linkage + void mf2(void(*)()); // the name of the function \tcode{mf2} has \Cpp{} language linkage; // the parameter has type ``pointer to C function'' }; } @@ -3484,7 +3489,7 @@ program is ill-formed; no diagnostic is required if the declarations appear in different translation units. \indextext{consistency!linkage specification}% -Except for functions with \Cpp linkage, a function declaration without a +Except for functions with \Cpp{} linkage, a function declaration without a linkage specification shall not precede the first linkage specification for that function. A function can be declared without a linkage specification after an explicit linkage specification has been seen; the @@ -3568,8 +3573,8 @@ \pnum \indextext{object!linkage specification}% \indextext{linkage!implementation-defined object}% -Linkage from \Cpp to objects defined in other languages and to objects -defined in \Cpp from other languages is \impldef{linkage of objects between \Cpp and other languages} and +Linkage from \Cpp{} to objects defined in other languages and to objects +defined in \Cpp{} from other languages is \impldef{linkage of objects between \Cpp{} and other languages} and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.% @@ -3587,19 +3592,19 @@ \begin{bnf} \nontermdef{attribute-specifier-seq}\br - attribute-specifier-seq\opt attribute-specifier + \opt{attribute-specifier-seq} attribute-specifier \end{bnf} \begin{bnf} \nontermdef{attribute-specifier}\br - \terminal{[} \terminal{[} attribute-using-prefix\opt{} attribute-list \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} \opt{attribute-using-prefix} attribute-list \terminal{]} \terminal{]}\br alignment-specifier \end{bnf} \begin{bnf} \nontermdef{alignment-specifier}\br - \terminal{alignas (} type-id \terminal{...}\opt{} \terminal{)}\br - \terminal{alignas (} constant-expression \terminal{...}\opt{} \terminal{)} + \terminal{alignas (} type-id \opt{\terminal{...}} \terminal{)}\br + \terminal{alignas (} constant-expression \opt{\terminal{...}} \terminal{)} \end{bnf} \begin{bnf} @@ -3609,15 +3614,15 @@ \begin{bnf} \nontermdef{attribute-list}\br - attribute\opt\br - attribute-list \terminal{,} attribute\opt\br + \opt{attribute}\br + attribute-list \terminal{,} \opt{attribute}\br attribute \terminal{...}\br attribute-list \terminal{,} attribute \terminal{...} \end{bnf} \begin{bnf} \nontermdef{attribute}\br - attribute-token attribute-argument-clause\opt + attribute-token \opt{attribute-argument-clause} \end{bnf} \begin{bnf} @@ -3638,7 +3643,7 @@ \begin{bnf} \nontermdef{attribute-argument-clause}\br - \terminal{(} balanced-token-seq\opt{} \terminal{)} + \terminal{(} \opt{balanced-token-seq} \terminal{)} \end{bnf} \begin{bnf} @@ -3649,9 +3654,9 @@ \begin{bnf} \nontermdef{balanced-token}\br - \terminal{(} balanced-token-seq\opt{} \terminal{)}\br - \terminal{[} balanced-token-seq\opt{} \terminal{]}\br - \terminal{\{} balanced-token-seq\opt{} \terminal{\}}\br + \terminal{(} \opt{balanced-token-seq} \terminal{)}\br + \terminal{[} \opt{balanced-token-seq} \terminal{]}\br + \terminal{\{} \opt{balanced-token-seq} \terminal{\}}\br \textnormal{any \grammarterm{token} other than a parenthesis, a bracket, or a brace} \end{bnf} @@ -3889,7 +3894,7 @@ int foo_array[10][10]; [[carries_dependency]] struct foo* f(int i) { - return foo_head[i].load(memory_order_consume); + return foo_head[i].load(memory_order::consume); } int g(int* x, int* y [[carries_dependency]]) { @@ -4076,7 +4081,7 @@ calls a function previously declared \tcode{nodiscard}, or whose return type is a possibly cv-qualified class or enumeration type marked \tcode{nodiscard}. Appearance of a nodiscard call as -a potentially-evaluated discarded-value expression\iref{expr} +a potentially-evaluated discarded-value expression\iref{expr.prop} is discouraged unless explicitly cast to \tcode{void}. Implementations should issue a warning in such cases. This is typically because discarding the return value diff --git a/source/declarators.tex b/source/declarators.tex index f6e285e4a0..dfb448b639 100644 --- a/source/declarators.tex +++ b/source/declarators.tex @@ -7,7 +7,7 @@ \indextext{initialization!class object|seealso{constructor}}% \indextext{\idxcode{*}|see{declarator, pointer}} \indextext{\idxcode{\&}|see{declarator, reference}}% -\indextext{\idxcode{::*}|see{declarator, pointer to member}}% +\indextext{\idxcode{::*}|see{declarator, pointer-to-member}}% \indextext{\idxcode{[]}|see{declarator, array}}% \indextext{\idxcode{()}|see{declarator, function}}% @@ -27,7 +27,7 @@ \begin{bnf} \nontermdef{init-declarator}\br - declarator initializer\opt\br + declarator \opt{initializer}\br declarator requires-clause \end{bnf} @@ -139,16 +139,16 @@ \begin{bnf} \nontermdef{noptr-declarator}\br - declarator-id attribute-specifier-seq\opt\br + declarator-id \opt{attribute-specifier-seq}\br noptr-declarator parameters-and-qualifiers\br - noptr-declarator \terminal{[} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt\br + noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{(} ptr-declarator \terminal{)} \end{bnf} \begin{bnf} \nontermdef{parameters-and-qualifiers}\br - \terminal{(} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt noexcept-specifier\opt attribute-specifier-seq\opt + \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\hspace*{\bnfindentinc}\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} @@ -158,15 +158,15 @@ \begin{bnf} \nontermdef{ptr-operator}\br - \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt\br - \terminal{\&} attribute-specifier-seq\opt\br - \terminal{\&\&} attribute-specifier-seq\opt\br - nested-name-specifier \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt + \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br + \terminal{\&} \opt{attribute-specifier-seq}\br + \terminal{\&\&} \opt{attribute-specifier-seq}\br + nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} \nontermdef{cv-qualifier-seq}\br - cv-qualifier cv-qualifier-seq\opt + cv-qualifier \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} @@ -183,7 +183,7 @@ \begin{bnf} \nontermdef{declarator-id}\br - \terminal{...}\opt id-expression + \opt{\terminal{...}} id-expression \end{bnf} \rSec1[dcl.name]{Type names} @@ -206,31 +206,31 @@ \begin{bnf} \nontermdef{type-id}\br - type-specifier-seq abstract-declarator\opt + type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{defining-type-id}\br - defining-type-specifier-seq abstract-declarator\opt + defining-type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{abstract-declarator}\br ptr-abstract-declarator\br - noptr-abstract-declarator\opt parameters-and-qualifiers trailing-return-type\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br abstract-pack-declarator \end{bnf} \begin{bnf} \nontermdef{ptr-abstract-declarator}\br noptr-abstract-declarator\br - ptr-operator ptr-abstract-declarator\opt + ptr-operator \opt{ptr-abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{noptr-abstract-declarator}\br - noptr-abstract-declarator\opt parameters-and-qualifiers\br - noptr-abstract-declarator\opt{} \terminal{[} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers\br + \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{(} ptr-abstract-declarator \terminal{)} \end{bnf} @@ -243,7 +243,7 @@ \begin{bnf} \nontermdef{noptr-abstract-pack-declarator}\br noptr-abstract-pack-declarator parameters-and-qualifiers\br - noptr-abstract-pack-declarator \terminal{[} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt\br + noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{...} \end{bnf} @@ -458,7 +458,7 @@ where \tcode{T} -is of the form \grammarterm{attribute-specifier-seq}\opt{} +is of the form \opt{\grammarterm{attribute-specifier-seq}} \grammarterm{decl-specifier-seq} and \tcode{D} @@ -499,7 +499,7 @@ \pnum In a declaration -\grammarterm{attribute-specifier-seq}\opt{} +\opt{\grammarterm{attribute-specifier-seq}} \tcode{T} \tcode{D} where @@ -544,7 +544,7 @@ has the form \begin{ncsimplebnf} -\terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt{} \terminal{D1} +\terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} \end{ncsimplebnf} and the type of the identifier in the declaration @@ -657,8 +657,8 @@ has either of the forms \begin{ncsimplebnf} -\terminal{\&} attribute-specifier-seq\opt{} \terminal{D1}\br -\terminal{\&\&} attribute-specifier-seq\opt{} \terminal{D1} +\terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br +\terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1} \end{ncsimplebnf} and the type of the identifier in the declaration @@ -838,7 +838,7 @@ \end{note} \rSec2[dcl.mptr]{Pointers to members}% -\indextext{declarator!pointer to member} +\indextext{declarator!pointer-to-member} \pnum In a declaration @@ -849,7 +849,7 @@ has the form \begin{ncsimplebnf} -nested-name-specifier \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt{} \terminal{D1} +nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} \end{ncsimplebnf} and the @@ -870,7 +870,7 @@ \pnum \begin{example}% -\indextext{example!pointer to member} +\indextext{example!pointer-to-member} \begin{codeblock} struct X { @@ -941,9 +941,9 @@ \begin{note} See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. The type ``pointer to member'' is distinct from the type ``pointer'', -that is, a pointer to member is declared only by the pointer to member +that is, a pointer to member is declared only by the pointer-to-member declarator syntax, and never by the pointer declarator syntax. -There is no ``reference-to-member'' type in \Cpp. +There is no ``reference-to-member'' type in \Cpp{}. \end{note} \rSec2[dcl.array]{Arrays}% @@ -958,7 +958,7 @@ has the form \begin{ncsimplebnf} -\terminal{D1 [} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt +\terminal{D1 [} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq} \end{ncsimplebnf} and the type of the identifier in the declaration @@ -1229,8 +1229,8 @@ \tcode{D} has the form \begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt noexcept-specifier\opt attribute-specifier-seq\opt +\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\hspace*{\bnfindentinc}\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} @@ -1246,10 +1246,10 @@ \tcode{D} is ``\placeholder{derived-declarator-type-list} -\tcode{noexcept}\opt +\opt{\tcode{noexcept}} function of (\grammarterm{parameter-declaration-clause}) -\grammarterm{cv-qualifier-seq}\opt{} \grammarterm{ref-qualifier}\opt{} +\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} returning \tcode{T}'', where the optional \tcode{noexcept} is present if and only if @@ -1266,8 +1266,8 @@ has the form \begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt noexcept-specifier\opt attribute-specifier-seq\opt trailing-return-type +\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\hspace*{\bnfindentinc}\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} trailing-return-type \end{ncsimplebnf} and the type of the contained @@ -1284,10 +1284,10 @@ \tcode{D} is ``\placeholder{derived-declarator-type-list} -\tcode{noexcept}\opt +\opt{\tcode{noexcept}} function of (\grammarterm{parameter-declaration-clause}) -\grammarterm{cv-qualifier-seq}\opt \grammarterm{ref-qualifier}\opt +\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} returning \tcode{U}'', where \tcode{U} is the type specified by the \grammarterm{trailing-return-type}, and @@ -1303,7 +1303,7 @@ \indextext{declaration!function}% \begin{bnf} \nontermdef{parameter-declaration-clause}\br - parameter-declaration-list\opt{} \terminal{...}\opt\br + \opt{parameter-declaration-list} \opt{\terminal{...}}\br parameter-declaration-list \terminal{, ...} \end{bnf} @@ -1315,10 +1315,10 @@ \begin{bnf} \nontermdef{parameter-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq declarator\br - attribute-specifier-seq\opt decl-specifier-seq declarator \terminal{=} initializer-clause\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt{} \terminal{=} initializer-clause + \opt{attribute-specifier-seq} decl-specifier-seq declarator\br + \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator}\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} @@ -1386,7 +1386,7 @@ \begin{note} The standard header \tcode{} -\indextext{\idxhdr{cstdarg}}% +\indexhdr{cstdarg}% contains a mechanism for accessing arguments passed using the ellipsis (see~\ref{expr.call} and~\ref{support.runtime}). \end{note} @@ -1472,7 +1472,7 @@ the \grammarterm{cv-qualifier-seq}, and the exception specification, but not the default arguments\iref{dcl.fct.default} -or \grammarterm{requires-clause}{s}\iref{temp}, +or the trailing \grammarterm{requires-clause}\iref{dcl.decl}, are part of the function type. \begin{note} Function types are checked during the assignments and initializations of @@ -1540,7 +1540,7 @@ of a function need not be the same. If a parameter name is present in a function declaration that is not a definition, it cannot be used outside of -its function declarator because that is the extent of its potential scope\iref{basic.scope.proto}. +its function declarator because that is the extent of its potential scope\iref{basic.scope.param}. \end{note} \pnum @@ -1844,8 +1844,10 @@ \end{example} \pnum -A local variable shall not appear as a potentially-evaluated expression +\begin{note} +A local variable cannot be odr-used\iref{basic.def.odr} in a default argument. +\end{note} \begin{example} \begin{codeblock} void f() { @@ -1984,13 +1986,13 @@ % \begin{bnf} \nontermdef{function-definition}\br - attribute-specifier-seq\opt decl-specifier-seq\opt declarator virt-specifier-seq\opt function-body\br - attribute-specifier-seq\opt decl-specifier-seq\opt declarator requires-clause function-body + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq} function-body\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause function-body \end{bnf} \begin{bnf} \nontermdef{function-body}\br - ctor-initializer\opt compound-statement\br + \opt{ctor-initializer} compound-statement\br function-try-block\br \terminal{= default ;}\br \terminal{= delete ;} @@ -2106,17 +2108,39 @@ A function that is explicitly defaulted shall \begin{itemize} -\item be a special member function, - -\item have the same declared function type (except for possibly differing -\grammarterm{ref-qualifier}{s} and except that in the case of a copy constructor or -copy assignment operator, the parameter type may be ``reference to non-const \tcode{T}'', -where \tcode{T} is the name of the member function's class) as if it had been implicitly -declared, and +\item be a special member function or a comparison operator +(\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}), and \item not have default arguments. \end{itemize} +% FIXME: there's no such thing as an implicit declaration of a comparison operator +\pnum +The type \tcode{T}$_1$ of an explicitly defaulted function \tcode{F} +is allowed to differ from the type \tcode{T}$_2$ it would have had +if it were implicitly declared, as follows: +\begin{itemize} +\item + \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; and +\item + if \tcode{T}$_2$ has a parameter of type \tcode{const C\&}, + the corresponding parameter of \tcode{T}$_1$ may be of type \tcode{C\&}. +\end{itemize} +If \tcode{T}$_1$ differs from \tcode{T}$_2$ in any other way, then: +\begin{itemize} +\item + if \tcode{F} is an assignment operator, and + the return type of \tcode{T}$_1$ differs from + the return type of \tcode{T}$_2$ or + \tcode{T}$_1${'s} parameter type is not a reference, + the program is ill-formed; +\item + otherwise, if \tcode{F} is explicitly defaulted on its first declaration, + it is defined as deleted; +\item + otherwise, the program is ill-formed. +\end{itemize} + \pnum An explicitly-defaulted function that is not defined as deleted may be declared \tcode{constexpr} only if it would have been implicitly declared as @@ -2125,17 +2149,6 @@ it is implicitly considered to be \tcode{constexpr} if the implicit declaration would be. -\pnum -If a function that is explicitly defaulted is declared with a -\grammarterm{noexcept-specifier} that does not produce -the same exception specification -as the implicit declaration\iref{except.spec}, then - -\begin{itemize} -\item if the function is explicitly defaulted on its first declaration, it is defined as deleted; -\item otherwise, the program is ill-formed. -\end{itemize} - \pnum \begin{example} \begin{codeblock} @@ -2238,7 +2251,7 @@ \end{example} \begin{example} -One can make a class uncopyable, i.e. move-only, by using deleted +One can make a class uncopyable, i.e., move-only, by using deleted definitions of the copy constructor and copy assignment operator, and then providing defaulted definitions of the move constructor and move assignment operator. \begin{codeblock} @@ -2295,7 +2308,7 @@ is defined as-if by \begin{ncbnf} -attribute-specifier-seq\opt{} decl-specifier-seq ref-qualifier\opt{} \terminal{e} initializer \terminal{;} +\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{e} initializer \terminal{;} \end{ncbnf} where @@ -2305,7 +2318,7 @@ The type of the \grammarterm{id-expression} \tcode{e} is called \tcode{E}. \begin{note} -\tcode{E} is never a reference type\iref{expr}. +\tcode{E} is never a reference type\iref{expr.prop}. \end{note} \pnum @@ -2345,10 +2358,15 @@ \end{note} In either case, \tcode{e} is an lvalue if the type of the entity \tcode{e} is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ -designated by \tcode{std::tuple_element::type}, each \tcode{v}$_i$ -is a variable of type ``reference to $\tcode{T}_i$'' initialized with the -initializer, where the reference is an lvalue reference if the initializer is -an lvalue and an rvalue reference otherwise; the referenced type is $\tcode{T}_i$. +designated by \tcode{std::tuple_element::type}, +variables are introduced with unique names $\tcode{r}_i$ +of type ``reference to $\tcode{T}_i$'' +initialized with the initializer~(\ref{dcl.init.ref}), +where the reference is an lvalue reference if the initializer is +an lvalue and an rvalue reference otherwise. +Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ +that refers to the object bound to $\tcode{r}_i$; +the referenced type is $\tcode{T}_i$. \pnum Otherwise, all of \tcode{E}'s non-static data members shall be public direct @@ -2378,15 +2396,11 @@ \indextext{initialization|(} \pnum -A declarator can specify an initial value for the -identifier being declared. -The identifier designates a variable being initialized. -The process of initialization described in the -remainder of~\ref{dcl.init} -applies also to initializations -specified by other syntactic contexts, such as the initialization -of function parameters\iref{expr.call} or -the initialization of return values\iref{stmt.return}. +The process of initialization described in this subclause applies to +all initializations regardless of syntactic context, including the +initialization of a function parameter\iref{expr.call}, the +initialization of a return value\iref{stmt.return}, or when an +initializer follows a declarator. \begin{bnf} \nontermdef{initializer}\br @@ -2408,15 +2422,15 @@ \begin{bnf} \nontermdef{braced-init-list}\br - \terminal{\{} initializer-list \terminal{,\opt} \terminal{\}}\br - \terminal{\{} designated-initializer-list \terminal{,\opt} \terminal{\}}\br + \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br + \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br \terminal{\{} \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{initializer-list}\br - initializer-clause \terminal{...}\opt\br - initializer-list \terminal{,} initializer-clause \terminal{...}\opt + initializer-clause \opt{\terminal{...}}\br + initializer-list \terminal{,} initializer-clause \opt{\terminal{...}} \end{bnf} \begin{bnf} @@ -2441,6 +2455,12 @@ braced-init-list \end{bnf} +\begin{note} +The rules in this subclause apply even if the grammar permits only +the \grammarterm{brace-or-equal-initializer} form +of \grammarterm{initializer} in a given context. +\end{note} + \pnum Except for objects declared with the \tcode{constexpr} specifier, for which see~\ref{dcl.constexpr}, an \grammarterm{initializer} in the definition of a variable can consist of @@ -2686,7 +2706,7 @@ \ref{expr.type.conv}, \ref{expr.static.cast}, \ref{expr.cast}) to an unsigned narrow character type or \tcode{std::byte} type\iref{cstddef.syn}, or -\item a discarded-value expression\iref{expr}, +\item a discarded-value expression\iref{expr.prop}, \end{itemize} then the result of the operation is an indeterminate value. @@ -3016,7 +3036,7 @@ to convert the expression, the program is ill-formed. \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 section if the element is an aggregate. \end{note} +of the rules in this subclause if the element is an aggregate. \end{note} \end{itemize} \begin{example} \begin{codeblock} @@ -3167,7 +3187,7 @@ shall not be used as the \grammarterm{initializer-clause} for an array of unknown bound.\footnote{The syntax provides for empty \grammarterm{initializer-list}{s}, -but nonetheless \Cpp does not have zero length arrays.} +but nonetheless \Cpp{} does not have zero length arrays.} \begin{note} A default member initializer does not determine the bound for a member array of unknown bound. Since the default member initializer is @@ -3893,7 +3913,7 @@ \item Otherwise, if \tcode{T} is a character array and the initializer list has a single element that is an appropriately-typed string literal\iref{dcl.init.string}, -initialization is performed as described in that section. +initialization is performed as described in that subclause. \item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is performed\iref{dcl.init.aggr}. diff --git a/source/derived.tex b/source/derived.tex index 6833ebf167..f4846210c5 100644 --- a/source/derived.tex +++ b/source/derived.tex @@ -23,20 +23,20 @@ \begin{bnf} \nontermdef{base-specifier-list}\br - base-specifier \terminal{...}\opt\br - base-specifier-list \terminal{,} base-specifier \terminal{...}\opt + base-specifier \opt{\terminal{...}}\br + base-specifier-list \terminal{,} base-specifier \opt{\terminal{...}} \end{bnf} \begin{bnf} \nontermdef{base-specifier}\br - attribute-specifier-seq\opt class-or-decltype\br - attribute-specifier-seq\opt{} \terminal{virtual} access-specifier\opt class-or-decltype\br - attribute-specifier-seq\opt access-specifier \terminal{virtual}\opt class-or-decltype + \opt{attribute-specifier-seq} class-or-decltype\br + \opt{attribute-specifier-seq} \terminal{virtual} \opt{access-specifier} class-or-decltype\br + \opt{attribute-specifier-seq} access-specifier \opt{\terminal{virtual}} class-or-decltype \end{bnf} \begin{bnf} \nontermdef{class-or-decltype}\br - nested-name-specifier\opt class-name\br + \opt{nested-name-specifier} class-name\br nested-name-specifier \terminal{template} simple-template-id\br decltype-specifier \end{bnf} @@ -687,7 +687,7 @@ \end{example} \pnum -A virtual function shall not have a \grammarterm{requires-clause}. +A virtual function shall not have a trailing \grammarterm{requires-clause}\iref{dcl.decl}. \begin{example} \begin{codeblock} struct A { @@ -792,7 +792,7 @@ cannot be a non-member\iref{dcl.fct.spec} function. Nor can a virtual function be a static member, since a virtual function call relies on a specific object for determining which function to invoke. A virtual -function declared in one class can be declared a \tcode{friend} in +function declared in one class can be declared a friend~(\ref{class.friend}) in another class. \end{note} diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 1dcb7f3f4f..220bdd6ad8 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -4,7 +4,7 @@ \rSec1[diagnostics.general]{General} \pnum -This Clause describes components that \Cpp programs may use to detect and +This Clause describes components that \Cpp{} programs may use to detect and report error conditions. \pnum @@ -24,8 +24,8 @@ \rSec1[std.exceptions]{Exception classes} \pnum -The \Cpp standard library provides classes to be used to report certain errors\iref{res.on.exception.handling} in -\Cpp programs. +The \Cpp{} standard library provides classes to be used to report certain errors\iref{res.on.exception.handling} in +\Cpp{} programs. In the error model reflected in these classes, errors are divided into two broad categories: \term{logic} @@ -43,14 +43,12 @@ They cannot be easily predicted in advance. The header \tcode{} -\indextext{\idxhdr{stdexcept}}% -\indexlibrary{\idxhdr{stdexcept}}% -defines several types of predefined exceptions for reporting errors in a \Cpp program. +\indexhdr{stdexcept}% +defines several types of predefined exceptions for reporting errors in a \Cpp{} program. These exceptions are related by inheritance. \rSec2[stdexcept.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{stdexcept}}% -\indexlibrary{\idxhdr{stdexcept}}% +\indexhdr{stdexcept}% \indexlibrary{\idxcode{logic_error}}% \indexlibrary{\idxcode{domain_error}}% \indexlibrary{\idxcode{invalid_argument}}% @@ -540,21 +538,19 @@ \pnum The header \tcode{} -provides a macro for documenting \Cpp program assertions and a mechanism +provides a macro for documenting \Cpp{} program assertions and a mechanism for disabling the assertion checks. \rSec2[cassert.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cassert}}% -\indexlibrary{\idxhdr{cassert}}% +\indexhdr{cassert}% \indexlibrary{\idxcode{assert}}% \begin{codeblock} #define assert(E) @\seebelow@ \end{codeblock} \pnum -\indextext{\idxhdr{assert.h}}% -\indexlibrary{\idxhdr{assert.h}}% +\indexhdr{assert.h}% \indextext{static_assert@\tcode{static_assert}!not macro}% The contents are the same as the C standard library header \tcode{}, @@ -580,8 +576,7 @@ \rSec1[errno]{Error numbers} \pnum -\indextext{\idxhdr{errno.h}}% -\indexlibrary{\idxhdr{errno.h}}% +\indexhdr{errno.h}% The contents of the header \tcode{} are the same as the POSIX header \tcode{}, except that \tcode{errno} shall be defined as a macro. \begin{note} @@ -591,8 +586,7 @@ \rSec2[cerrno.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cerrno}}% -\indexlibrary{\idxhdr{cerrno}}% +\indexhdr{cerrno}% \indexlibrary{\idxcode{errno}}% \indexlibrary{\idxcode{E2BIG}}% \indexlibrary{\idxcode{EACCES}}% @@ -764,7 +758,7 @@ \pnum This subclause describes components that the standard library and -\Cpp programs may use to report error conditions originating from +\Cpp{} programs may use to report error conditions originating from the operating system or other low-level application program interfaces. \pnum @@ -774,8 +768,7 @@ libraries unchanged. \rSec2[system_error.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{system_error}}% -\indexlibrary{\idxhdr{system_error}}% +\indexhdr{system_error}% \indexlibrary{\idxcode{error_category}}% \indexlibrary{\idxcode{error_code}}% \indexlibrary{\idxcode{error_condition}}% @@ -794,10 +787,10 @@ class error_condition; class system_error; - template + template struct is_error_code_enum : public false_type {}; - template + template struct is_error_condition_enum : public false_type {}; enum class errc { @@ -881,12 +874,12 @@ wrong_protocol_type, // \tcode{EPROTOTYPE} }; - template <> struct is_error_condition_enum : true_type {}; + template<> struct is_error_condition_enum : true_type {}; // \ref{syserr.errcode.nonmembers}, non-member functions error_code make_error_code(errc e) noexcept; - template + template basic_ostream& operator<<(basic_ostream& os, const error_code& ec); @@ -906,14 +899,14 @@ bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; // \ref{syserr.hash}, hash support - template struct hash; - template <> struct hash; - template <> struct hash; + template struct hash; + template<> struct hash; + template<> struct hash; // \ref{syserr}, system error support - template + template inline constexpr bool is_error_code_enum_v = is_error_code_enum::value; - template + template inline constexpr bool is_error_condition_enum_v = is_error_condition_enum::value; } \end{codeblock} @@ -939,7 +932,7 @@ Classes may be derived from \tcode{error_category} to support categories of errors in addition to those defined in this document. Such classes shall behave as specified in this -subclause. \begin{note} \tcode{error_category} objects are +subclause~\ref{syserr.errcat}. \begin{note} \tcode{error_category} objects are passed by reference, and two such objects are equal if they have the same address. This means that applications using custom \tcode{error_category} types should create a single object of each @@ -1180,12 +1173,12 @@ // \ref{syserr.errcode.constructors}, constructors error_code() noexcept; error_code(int val, const error_category& cat) noexcept; - template + template error_code(ErrorCodeEnum e) noexcept; // \ref{syserr.errcode.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; - template + template error_code& operator=(ErrorCodeEnum e) noexcept; void clear() noexcept; @@ -1204,7 +1197,7 @@ // \ref{syserr.errcode.nonmembers}, non-member functions error_code make_error_code(errc e) noexcept; - template + template basic_ostream& operator<<(basic_ostream& os, const error_code& ec); } @@ -1240,7 +1233,7 @@ \indexlibrary{\idxcode{error_code}!constructor}% \begin{itemdecl} -template +template error_code(ErrorCodeEnum e) noexcept; \end{itemdecl} @@ -1270,7 +1263,7 @@ \indexlibrarymember{operator=}{error_code}% \begin{itemdecl} -template +template error_code& operator=(ErrorCodeEnum e) noexcept; \end{itemdecl} @@ -1363,7 +1356,7 @@ \indexlibrarymember{operator<<}{error_code}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream& os, const error_code& ec); \end{itemdecl} @@ -1391,12 +1384,12 @@ // \ref{syserr.errcondition.constructors}, constructors error_condition() noexcept; error_condition(int val, const error_category& cat) noexcept; - template + template error_condition(ErrorConditionEnum e) noexcept; // \ref{syserr.errcondition.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; - template + template error_condition& operator=(ErrorConditionEnum e) noexcept; void clear() noexcept; @@ -1443,7 +1436,7 @@ \indexlibrary{\idxcode{error_condition}!constructor}% \begin{itemdecl} -template +template error_condition(ErrorConditionEnum e) noexcept; \end{itemdecl} @@ -1474,7 +1467,7 @@ \indexlibrarymember{operator=}{error_condition}% \begin{itemdecl} -template +template error_condition& operator=(ErrorConditionEnum e) noexcept; \end{itemdecl} @@ -1656,8 +1649,8 @@ \indexlibrary{\idxcode{hash}!\idxcode{error_code}}% \begin{itemdecl} -template <> struct hash; -template <> struct hash; +template<> struct hash; +template<> struct hash; \end{itemdecl} \begin{itemdescr} @@ -1799,8 +1792,8 @@ \begin{itemdescr} \pnum -\returns An \ntbs incorporating the arguments supplied in the constructor. +\returns An \ntbs{} incorporating the arguments supplied in the constructor. -\begin{note} The returned \ntbs might be the contents of \tcode{what_arg + ": " + +\begin{note} The returned \ntbs{} might be the contents of \tcode{what_arg + ": " + code.message()}.\end{note} \end{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index ce99ca1f12..76e6ca95be 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -26,12 +26,12 @@ % \begin{bnf} \nontermdef{function-try-block}\br - \terminal{try} ctor-initializer\opt compound-statement handler-seq + \terminal{try} \opt{ctor-initializer} compound-statement handler-seq \end{bnf} \begin{bnf} \nontermdef{handler-seq}\br - handler handler-seq\opt + handler \opt{handler-seq} \end{bnf} \indextext{\idxcode{catch}}% @@ -43,8 +43,8 @@ \begin{bnf} \nontermdef{exception-declaration}\br - attribute-specifier-seq\opt type-specifier-seq declarator\br - attribute-specifier-seq\opt type-specifier-seq abstract-declarator\opt\br + \opt{attribute-specifier-seq} type-specifier-seq declarator\br + \opt{attribute-specifier-seq} type-specifier-seq \opt{abstract-declarator}\br \terminal{...} \end{bnf} @@ -180,7 +180,7 @@ \end{example} \pnum -In this section, ``before'' and ``after'' refer to the +In this Clause, ``before'' and ``after'' refer to the ``sequenced before'' relation\iref{intro.execution}. \rSec1[except.throw]{Throwing an exception}% @@ -362,7 +362,7 @@ \indextext{unwinding!stack}% As control passes from the point where an exception is thrown to a handler, -destructors are invoked by a process, specified in this section, called +destructors are invoked by a process, specified in this subclause, called \defn{stack unwinding}. \pnum @@ -496,8 +496,8 @@ \tcode{T} is an unambiguous public base class of \tcode{E}, or \item% the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} -where \tcode{T} is a pointer or pointer to member type and -\tcode{E} is a pointer or pointer to member type +where \tcode{T} is a pointer or pointer-to-member type and +\tcode{E} is a pointer or pointer-to-member type that can be converted to \tcode{T} by one or more of \begin{itemize} @@ -512,7 +512,7 @@ \end{itemize} \item -the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer to member type and \tcode{E} is \tcode{std::nullptr_t}. +the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}. \end{itemize} @@ -520,7 +520,7 @@ A \grammarterm{throw-expression} whose operand is an integer literal with value zero does not match a handler of -pointer or pointer to member type. +pointer or pointer-to-member type. A handler of reference to array or function type is never a match for any exception object\iref{expr.throw}. \end{note} @@ -899,6 +899,15 @@ with no explicit \grammarterm{noexcept-specifier} has a non-throwing exception specification. +\pnum +The exception specification for a comparison operator +(\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}) +without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration +is potentially-throwing if and only if +the invocation of any comparison operator +in the implicit definition is potentially-throwing. + \pnum \begin{example} \begin{codeblock} diff --git a/source/expressions.tex b/source/expressions.tex index cd84a99873..8db845096a 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -13,6 +13,8 @@ \indextext{\idxcode{const_cast}|see{cast, const}}% \indextext{\idxcode{reinterpret_cast}|see{cast, reinterpret}} +\rSec1[expr.pre]{Preamble} + \pnum \indextext{expression|(}% \begin{note} @@ -31,7 +33,7 @@ expressions of class type\iref{class} or enumeration type\iref{dcl.enum}. Uses of overloaded operators are transformed into function calls as described in~\ref{over.oper}. Overloaded operators -obey the rules for syntax and evaluation order specified in \ref{expr}, +obey the rules for syntax and evaluation order specified in \ref{expr.compound}, but the requirements of operand type and value category are replaced by the rules for function call. Relations between operators, such as \tcode{++a} meaning \tcode{a+=1}, are not guaranteed for overloaded @@ -39,7 +41,7 @@ \end{note} \pnum -\ref{expr} defines the effects of operators when applied to types +Subclause \ref{expr.compound} defines the effects of operators when applied to types for which they have not been overloaded. Operator overloading shall not modify the rules for the \defnx{built-in operators}{operators!built-in}, that is, for operators applied to types for which they are defined by this @@ -48,7 +50,7 @@ considered where necessary to convert the operands to types appropriate for the built-in operator. If a built-in operator is selected, such conversions will be applied to the operands before the operation is -considered further according to the rules in \ref{expr}; +considered further according to the rules in subclause \ref{expr.compound}; see~\ref{over.match.oper}, \ref{over.built}. \pnum @@ -68,21 +70,60 @@ \end{note} \pnum -\indextext{expression!reference}% -If an expression initially has the type ``reference to -\tcode{T}''~(\ref{dcl.ref}, \ref{dcl.init.ref}), the type is adjusted to -\tcode{T} prior to any further analysis. The expression designates the -object or function denoted by the reference, and the expression -is an lvalue or an xvalue, depending on the expression. -\begin{note} -Before the lifetime of the reference has started or after it has ended, -the behavior is undefined (see~\ref{basic.life}). -\end{note} +The values of the floating operands and the results of floating +expressions may be represented in greater precision and range than that +required by the type; the types are not changed\ +thereby.\footnote{The cast and assignment operators must still perform their specific +conversions as described in~\ref{expr.cast}, \ref{expr.static.cast} +and~\ref{expr.ass}.} + +\rSec1[expr.prop]{Properties of expressions} +\rSec2[basic.lval]{Value category} \pnum -If a prvalue initially has the type ``\cv{}~\tcode{T}'', where -\tcode{T} is a cv-unqualified non-class, non-array type, the type of -the expression is adjusted to \tcode{T} prior to any further analysis. +Expressions are categorized according to the taxonomy in Figure~\ref{fig:categories}. + +\begin{importgraphic} +{Expression category taxonomy} +{fig:categories} +{valuecategories.pdf} +\end{importgraphic} + +\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, +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). +\begin{example} +Certain kinds of expressions involving rvalue references\iref{dcl.ref} yield xvalues, +such as a call to a function whose return type is an rvalue reference +or a cast to an rvalue reference type. +\end{example} +\item An \defn{lvalue} is a glvalue that is not an xvalue. +\item An \defn{rvalue} is a prvalue or an xvalue. +\end{itemize} + +\pnum +Every expression belongs to exactly one of the fundamental classifications in this +taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called +its \defn{value category}. \begin{note} The discussion of each built-in operator in +\ref{expr.compound} indicates the category of the value it yields and the value categories +of the operands it expects. For example, the built-in assignment operators expect that +the left operand is an lvalue and that the right operand is a prvalue and yield an +lvalue as the result. User-defined operators are functions, and the categories of +values they expect and yield are determined by their parameter and return types. \end{note} + +\pnum +\begin{note} +Historically, lvalues and rvalues were so-called +because they could appear on the left- and right-hand side of an assignment +(although this is no longer generally true); +glvalues are ``generalized'' lvalues, +prvalues are ``pure'' rvalues, +and xvalues are ``eXpiring'' lvalues. +Despite their names, these terms classify expressions, not values. +\end{note} \pnum \indextext{expression!rvalue reference}% @@ -123,20 +164,22 @@ \end{example} \pnum -In some contexts, \defnx{unevaluated operands}{unevaluated operand} -appear~(\ref{expr.prim.req}, -\ref{expr.typeid}, -\ref{expr.sizeof}, -\ref{expr.unary.noexcept}, -\ref{dcl.type.simple}, -\ref{temp}). -An unevaluated operand is not evaluated. +The \defnx{result}{result!prvalue} of a prvalue +is the value that the expression stores into its context. +A prvalue whose result is the value \placeholder{V} +is sometimes said to have or name the value \placeholder{V}. +The \defn{result object} of a prvalue +is the object initialized by the prvalue; +a prvalue +that is used to compute the value of an operand of an operator or +that has type \cv{}~\tcode{void} +has no result object. \begin{note} -In an unevaluated operand, a non-static class member may be -named\iref{expr.prim} and naming of objects or functions does not, by -itself, require that a definition be provided\iref{basic.def.odr}. -An unevaluated operand is considered a full-expression\iref{intro.execution}. +Except when the prvalue is the operand of a \grammarterm{decltype-specifier}, +a prvalue of class or array type always has a result object. +For a discarded prvalue, a temporary object is materialized; see \ref{expr.prop}. \end{note} +The \defnx{result}{result!glvalue} of a glvalue is the entity denoted by the expression. \pnum Whenever a glvalue expression appears as an operand of an operator that @@ -145,11 +188,19 @@ or function-to-pointer\iref{conv.func} standard conversions are applied to convert the expression to a prvalue. \begin{note} +An attempt to bind an rvalue reference to an lvalue is not such a context; see~\ref{dcl.init.ref}. +\end{note} +\begin{note} Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue expression of type \tcode{const int} can, for example, be used where a prvalue expression of type \tcode{int} is required. \end{note} +\begin{note} +There are no prvalue bit-fields; if a bit-field is converted to a +prvalue\iref{conv.lval}, a prvalue of the type of the bit-field is +created, which might then be promoted\iref{conv.prom}. +\end{note} \pnum Whenever a prvalue expression appears as an operand of an operator that @@ -158,102 +209,76 @@ applied to convert the expression to an xvalue. \pnum -\indextext{conversion!usual arithmetic}% -Many binary operators that expect operands of arithmetic or enumeration -type cause conversions and yield result types in a similar way. The -purpose is to yield a common type, which is also the type of the result. -This pattern is called the \term{usual arithmetic conversions}, -which are defined as follows: +The discussion of reference initialization in~\ref{dcl.init.ref} and of +temporaries in~\ref{class.temporary} indicates the behavior of lvalues +and rvalues in other significant contexts. -\begin{itemize} -\item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions -are performed; if the other operand does not have the same type, the expression is -ill-formed. - -\item If either operand is of type \tcode{long double}, the -other shall be converted to \tcode{long double}. - -\item Otherwise, if either operand is \tcode{double}, the other shall be -converted to \tcode{double}. - -\item Otherwise, if either operand is \tcode{float}, the other shall be -converted to \tcode{float}. +\pnum +Unless otherwise indicated\iref{expr.call}, +a prvalue shall always have complete type or the \tcode{void} type. +A glvalue shall not have type \cv{}~\tcode{void}. +\begin{note} +A glvalue may have complete or incomplete non-\tcode{void} type. +Class and array prvalues can have cv-qualified types; other prvalues +always have cv-unqualified types. See \ref{expr.prop}. +\end{note} -\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}, -\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: +\pnum +An lvalue is \defn{modifiable} unless its type is const-qualified +or is a function type. +\begin{note} +A program that attempts +to modify an object through a nonmodifiable lvalue expression or through an rvalue expression +is ill-formed~(\ref{expr.ass}, \ref{expr.post.incr}, \ref{expr.pre.incr}). +\end{note} +\pnum +If a program attempts to access the stored value of an object through a glvalue +of other than one of the following types the behavior is +undefined:\footnote{The intent of this list is to specify those circumstances in which an +object may or may not be aliased.} \begin{itemize} +\item the dynamic type of the object, -\item If both operands have the same type, no further conversion is -needed. +\item a cv-qualified version of the dynamic type of the object, -\item Otherwise, if both operands have signed integer types or both have -unsigned integer types, the operand with the type of lesser integer -conversion rank shall be converted to the type of the operand with -greater rank. +\item a type similar (as defined in~\ref{conv.qual}) to the dynamic type +of the object, -\item Otherwise, if the operand that has unsigned integer type has rank -greater than or equal to the rank of the type of the other operand, the -operand with signed integer type shall be converted to the type of the -operand with unsigned integer type. +\item a type that is the signed or unsigned type corresponding to the +dynamic type of the object, -\item Otherwise, if the type of the operand with signed integer type can -represent all of the values of the type of the operand with unsigned -integer type, the operand with unsigned integer type shall be converted -to the type of the operand with signed integer type. +\item a type that is the signed or unsigned type corresponding to a +cv-qualified version of the dynamic type of the object, -\item Otherwise, both operands shall be converted to the unsigned -integer type corresponding to the type of the operand with signed -integer type. -\end{itemize} -\end{itemize} +\item an aggregate or union type that includes one of the aforementioned types among its +elements or non-static data members (including, recursively, an element or non-static data member of a +subaggregate or contained union), -\pnum -In some contexts, an expression only appears for its side effects. Such an -expression is called a \defn{discarded-value expression}. -The array-to-pointer\iref{conv.array} -and function-to-pointer\iref{conv.func} standard conversions are not -applied. The lvalue-to-rvalue conversion\iref{conv.lval} is applied -if and only if -the expression is a glvalue of volatile-qualified type and it is one of the -following: +\item a type that is a (possibly cv-qualified) base class type of the dynamic type of +the object, -\begin{itemize} -\item \tcode{(} \grammarterm{expression} \tcode{)}, where - \grammarterm{expression} is one of these expressions, -\item \grammarterm{id-expression}\iref{expr.prim.id}, -\item subscripting\iref{expr.sub}, -\item class member access\iref{expr.ref}, -\item indirection\iref{expr.unary.op}, -\item pointer-to-member operation\iref{expr.mptr.oper}, -\item conditional expression\iref{expr.cond} where both the second and the - third operands are one of these expressions, or -\item comma expression\iref{expr.comma} where the right operand is one of - these expressions. +\item a \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} type. \end{itemize} -\begin{note} Using an overloaded operator causes a function call; the -above covers only operators with built-in meaning. -\end{note} -If the (possibly converted) expression is a prvalue, -the temporary materialization conversion\iref{conv.rval} is applied. +\rSec2[expr.type]{Type} + +\pnum +\indextext{expression!reference}% +If an expression initially has the type ``reference to +\tcode{T}''~(\ref{dcl.ref}, \ref{dcl.init.ref}), the type is adjusted to +\tcode{T} prior to any further analysis. The expression designates the +object or function denoted by the reference, and the expression +is an lvalue or an xvalue, depending on the expression. \begin{note} -If the expression is an lvalue of -class type, it must have a volatile copy constructor to initialize the -temporary object that is the result object of the lvalue-to-rvalue -conversion. \end{note} -The glvalue expression is evaluated and its value is discarded. +Before the lifetime of the reference has started or after it has ended, +the behavior is undefined (see~\ref{basic.life}). +\end{note} \pnum -The values of the floating operands and the results of floating -expressions may be represented in greater precision and range than that -required by the type; the types are not changed\ -thereby.\footnote{The cast and assignment operators must still perform their specific -conversions as described in~\ref{expr.cast}, \ref{expr.static.cast} -and~\ref{expr.ass}.} +If a prvalue initially has the type ``\cv{}~\tcode{T}'', where +\tcode{T} is a cv-unqualified non-class, non-array type, the type of +the expression is adjusted to \tcode{T} prior to any further analysis. \pnum The \defnx{cv-combined type}{type!cv-combined} of two types \tcode{T1} and \tcode{T2} @@ -279,7 +304,7 @@ The \defn{composite pointer type} of two operands \tcode{p1} and \tcode{p2} having types \tcode{T1} and \tcode{T2}, respectively, where at least one is a -pointer or pointer to member type or +pointer or pointer-to-member type or \tcode{std::nullptr_t}, is: \begin{itemize} @@ -339,6 +364,115 @@ \tcode{const int}''. \end{example} +\rSec2[expr.context]{Context dependence} + +\pnum +In some contexts, \defnx{unevaluated operands}{unevaluated operand} +appear~(\ref{expr.prim.req}, +\ref{expr.typeid}, +\ref{expr.sizeof}, +\ref{expr.unary.noexcept}, +\ref{dcl.type.simple}, +\ref{temp}). +An unevaluated operand is not evaluated. +\begin{note} +In an unevaluated operand, a non-static class member may be +named\iref{expr.prim} and naming of objects or functions does not, by +itself, require that a definition be provided\iref{basic.def.odr}. +An unevaluated operand is considered a full-expression\iref{intro.execution}. +\end{note} + +\pnum +In some contexts, an expression only appears for its side effects. Such an +expression is called a \defn{discarded-value expression}. +The array-to-pointer\iref{conv.array} +and function-to-pointer\iref{conv.func} standard conversions are not +applied. The lvalue-to-rvalue conversion\iref{conv.lval} is applied +if and only if +the expression is a glvalue of volatile-qualified type and it is one of the +following: + +\begin{itemize} +\item \tcode{(} \grammarterm{expression} \tcode{)}, where + \grammarterm{expression} is one of these expressions, +\item \grammarterm{id-expression}\iref{expr.prim.id}, +\item subscripting\iref{expr.sub}, +\item class member access\iref{expr.ref}, +\item indirection\iref{expr.unary.op}, +\item pointer-to-member operation\iref{expr.mptr.oper}, +\item conditional expression\iref{expr.cond} where both the second and the + third operands are one of these expressions, or +\item comma expression\iref{expr.comma} where the right operand is one of + these expressions. +\end{itemize} + +\begin{note} Using an overloaded operator causes a function call; the +above covers only operators with built-in meaning. +\end{note} +If the (possibly converted) expression is a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. +\begin{note} +If the expression is an lvalue of +class type, it must have a volatile copy constructor to initialize the +temporary object that is the result object of the lvalue-to-rvalue +conversion. \end{note} +The glvalue expression is evaluated and its value is discarded. + +\rSec1[expr.arith.conv]{Usual arithmetic conversions} + +\pnum +Many binary operators that expect operands of arithmetic or enumeration +type cause conversions and yield result types in a similar way. The +purpose is to yield a common type, which is also the type of the result. +This pattern is called the \defnx{usual arithmetic conversions}{conversion!usual arithmetic}, +which are defined as follows: + +\begin{itemize} +\item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions +are performed; if the other operand does not have the same type, the expression is +ill-formed. + +\item If either operand is of type \tcode{long double}, the +other shall be converted to \tcode{long double}. + +\item Otherwise, if either operand is \tcode{double}, the other shall be +converted to \tcode{double}. + +\item Otherwise, if either operand is \tcode{float}, the other shall be +converted to \tcode{float}. + +\item Otherwise, the integral promotions\iref{conv.prom} shall be +performed on both operands.\footnote{As a consequence, operands of type \tcode{bool}, \tcode{char16_t}, +\tcode{char32_t}, \tcode{wchar_t}, or an enumerated type are converted +to some integral type.} +Then the following rules shall be applied to the promoted operands: + +\begin{itemize} + +\item If both operands have the same type, no further conversion is +needed. + +\item Otherwise, if both operands have signed integer types or both have +unsigned integer types, the operand with the type of lesser integer +conversion rank shall be converted to the type of the operand with +greater rank. + +\item Otherwise, if the operand that has unsigned integer type has rank +greater than or equal to the rank of the type of the other operand, the +operand with signed integer type shall be converted to the type of the +operand with unsigned integer type. + +\item Otherwise, if the type of the operand with signed integer type can +represent all of the values of the type of the operand with unsigned +integer type, the operand with unsigned integer type shall be converted +to the type of the operand with signed integer type. + +\item Otherwise, both operands shall be converted to the unsigned +integer type corresponding to the type of the operand with signed +integer type. +\end{itemize} +\end{itemize} + \rSec1[expr.prim]{Primary expressions}% \indextext{expression!primary|(} @@ -508,7 +642,7 @@ \pnum A program that refers explicitly or implicitly -to a function with a \grammarterm{requires-clause} +to a function with a trailing \grammarterm{requires-clause} whose \grammarterm{constraint-expression} is not satisfied, other than to declare it, is ill-formed. @@ -526,7 +660,7 @@ In the declaration of \tcode{p2}, those constraints are required to be satisfied even though -\tcode{f} is an unevaluated operand\iref{expr}. +\tcode{f} is an unevaluated operand\iref{expr.prop}. \end{example} \rSec3[expr.prim.id.unqual]{Unqualified names} @@ -537,8 +671,8 @@ operator-function-id\br conversion-function-id\br literal-operator-id\br - \terminal{\tilde} class-name\br - \terminal{\tilde} decltype-specifier\br + \terminal{\~} class-name\br + \terminal{\~} decltype-specifier\br template-id \end{bnf} @@ -552,15 +686,52 @@ \grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for \grammarterm{template-id}{s}, see~\ref{temp.names}. A \grammarterm{class-name} or \grammarterm{decltype-specifier} -prefixed by \tcode{\tilde} denotes a destructor; see~\ref{class.dtor}. +prefixed by \tcode{\~} denotes a destructor; see~\ref{class.dtor}. Within the definition of a non-static member function, an \grammarterm{identifier} that names a non-static member is transformed to a class member access expression~(\ref{class.mfct.non-static}). \end{note} -The type of the expression is the type of the \grammarterm{identifier}. The -result is the entity denoted by the identifier. The expression is an lvalue -if the entity is a function, variable, or data member and a prvalue otherwise; + +\pnum +The result is the entity denoted by the identifier. +If the entity is a local entity +and naming it from outside of an unevaluated operand +within the declarative region where the \grammarterm{unqualified-id} appears +would result in some intervening \grammarterm{lambda-expression} +capturing it by copy\iref{expr.prim.lambda.capture}, +the type of the expression is +the type of a class member access expression\iref{expr.ref} +naming the non-static data member +that would be declared for such a capture +in the closure object of +the innermost such intervening \grammarterm{lambda-expression}. +\begin{note} +If that \grammarterm{lambda-expression} is not declared \tcode{mutable}, +the type of such an identifier will typically be \tcode{const} qualified. +\end{note} +Otherwise, the type of the expression is the type of the result. +\begin{note} +The type will be adjusted as described in \ref{expr.type} +if it is cv-qualified or is a reference type. +\end{note} +The expression is an lvalue +if the entity is a function, variable, or data member +and a prvalue otherwise\iref{basic.lval}; it is a bit-field if the identifier designates a bit-field\iref{dcl.struct.bind}. +\begin{example} +\begin{codeblock} +void f() { + float x, &r = x; + [=] { + decltype(x) y1; // \tcode{y1} has type \tcode{float} + decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} because this lambda + // is not \tcode{mutable} and \tcode{x} is an lvalue + decltype(r) r1 = y1; // \tcode{r1} has type \tcode{float\&} + decltype((r)) r2 = y2; // \tcode{r2} has type \tcode{float const\&} + }; +} +\end{codeblock} +\end{example} \rSec3[expr.prim.id.qual]{Qualified names} @@ -569,7 +740,7 @@ % \begin{bnf} \nontermdef{qualified-id}\br - nested-name-specifier \terminal{template}\opt unqualified-id + nested-name-specifier \opt{\terminal{template}} unqualified-id \end{bnf} \indextext{operator!scope resolution}% @@ -582,7 +753,7 @@ namespace-name \terminal{::}\br decltype-specifier \terminal{::}\br nested-name-specifier identifier \terminal{::}\br - nested-name-specifier \terminal{template}\opt simple-template-id \terminal{::} + nested-name-specifier \opt{\terminal{template}} simple-template-id \terminal{::} \end{bnf} \pnum @@ -606,10 +777,10 @@ point in its potential scope\iref{basic.scope.class}. \end{note} Where -\grammarterm{class-name} \tcode{::\tilde}~\grammarterm{class-name} is used, +\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{\tilde}~\grammarterm{decltype-specifier} also denotes the destructor, +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 @@ -650,19 +821,22 @@ \begin{bnf} \nontermdef{lambda-expression}\br - lambda-introducer lambda-declarator\opt{} compound-statement\br - lambda-introducer \tcode{<} template-parameter-list \tcode{>} lambda-declarator\opt{} compound-statement + lambda-introducer compound-statement\br + lambda-introducer lambda-declarator \opt{requires-clause} compound-statement\br + lambda-introducer \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause} compound-statement\br + lambda-introducer \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause}\br + \hspace*{\bnfindentinc}lambda-declarator \opt{requires-clause} compound-statement \end{bnf} \begin{bnf} \nontermdef{lambda-introducer}\br - \terminal{[} lambda-capture\opt{} \terminal{]} + \terminal{[} \opt{lambda-capture} \terminal{]} \end{bnf} \begin{bnf} \nontermdef{lambda-declarator}\br - \terminal{(} parameter-declaration-clause \terminal{)} decl-specifier-seq\opt\br - \hspace*{\bnfindentinc}noexcept-specifier\opt attribute-specifier-seq\opt trailing-return-type\opt + \terminal{(} parameter-declaration-clause \terminal{)} \opt{decl-specifier-seq}\br + \hspace*{\bnfindentinc}\opt{noexcept-specifier} \opt{attribute-specifier-seq} \opt{trailing-return-type} \end{bnf} \pnum @@ -679,15 +853,7 @@ \pnum A \grammarterm{lambda-expression} is a prvalue -whose result object is called the \defn{closure object}. A -\grammarterm{lambda-expression} shall not appear in an unevaluated operand\iref{expr}, -in a \grammarterm{template-argument}, -in an \grammarterm{alias-declaration}, -in a typedef declaration, or in the declaration of a function or function -template outside its function body and default arguments. -\begin{note} -The intention is to prevent lambdas from appearing in a signature. -\end{note} +whose result object is called the \defn{closure object}. \begin{note} A closure object behaves like a function object\iref{function.objects}.\end{note} @@ -696,6 +862,9 @@ In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, each \grammarterm{decl-specifier} shall either be \tcode{mutable} or \tcode{constexpr}. +\begin{note} +The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}. +\end{note} \pnum If a \grammarterm{lambda-expression} does not include a @@ -749,12 +918,9 @@ \begin{itemize} \item the size and/or alignment of the closure type, -\item whether the closure type is trivially copyable\iref{class}, - -\item whether the closure type is a standard-layout class\iref{class}, -or +\item whether the closure type is trivially copyable\iref{class}, or -\item whether the closure type is a POD class\iref{class}. +\item whether the closure type is a standard-layout class\iref{class}. \end{itemize} An implementation shall not add members of rvalue reference type to the closure @@ -782,6 +948,12 @@ \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 \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{example} \begin{codeblock} auto glambda = [](auto a, auto&& b) { return a < b; }; @@ -861,11 +1033,31 @@ \end{codeblock} \end{example} +\pnum +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}, +or a trailing \grammarterm{requires-clause}\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +template concept C1 = @\commentellip@; +template concept C2 = @\commentellip@; +template concept C3 = @\commentellip@; + +auto f = [] requires C2 + (T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3 { + // \tcode{T2} is a constrained parameter, + // \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} + \pnum The closure type for a non-generic \grammarterm{lambda-expression} with no \grammarterm{lambda-capture} +whose constraints (if any) are satisfied has a conversion function to pointer to -function with \Cpp language linkage\iref{dcl.link} having +function with \Cpp{} language linkage\iref{dcl.link} having the same parameter and return types as the closure type's function call operator. The conversion is to ``pointer to \tcode{noexcept} function'' if the function call operator @@ -1000,8 +1192,13 @@ \pnum The closure type associated with a \grammarterm{lambda-expression} has no -default constructor and a deleted copy assignment operator. It has a -defaulted copy constructor and a defaulted move constructor\iref{class.copy}. +default constructor +if the \grammarterm{lambda-expression} has a \grammarterm{lambda-capture} +and a defaulted default constructor otherwise. +It has a defaulted copy constructor and a defaulted move constructor\iref{class.copy}. +It has a deleted copy assignment operator if the \grammarterm{lambda-expression} +has a \grammarterm{lambda-capture} and defaulted copy and move assignment +operators otherwise. \begin{note} These special member functions are implicitly defined as usual, and might therefore be defined as deleted. \end{note} @@ -1013,7 +1210,7 @@ A member of a closure type shall not be explicitly instantiated\iref{temp.explicit}, explicitly specialized\iref{temp.expl.spec}, or -named in a \tcode{friend} declaration\iref{class.friend}. +named in a friend declaration\iref{class.friend}. \rSec3[expr.prim.lambda.capture]{Captures}% @@ -1032,8 +1229,8 @@ \begin{bnf} \nontermdef{capture-list}\br - capture \terminal{...\opt}\br - capture-list \terminal{,} capture \terminal{...\opt} + capture \opt{\terminal{...}}\br + capture-list \terminal{,} capture \opt{\terminal{...}} \end{bnf} \begin{bnf} @@ -1074,7 +1271,7 @@ ``\tcode{this}'', or ``\tcode{* this}''. \begin{note} The form \tcode{[\&,this]} is redundant but accepted -for compatibility with ISO \CppXIV. \end{note} +for compatibility with ISO \CppXIV{}. \end{note} Ignoring appearances in \grammarterm{initializer}{s} of \grammarterm{init-capture}{s}, an identifier or \tcode{this} shall not appear more than once in a @@ -1095,25 +1292,26 @@ \end{example} \pnum -A \grammarterm{lambda-expression} whose smallest enclosing scope is a block -scope\iref{basic.scope.block} is a \defn{local lambda expression}; any other +A \grammarterm{lambda-expression} +is a \defn{local lambda expression} +if its innermost enclosing scope is a block scope\iref{basic.scope.block}, +or if it appears within a default member initializer +and its innermost enclosing scope is +the corresponding class scope\iref{basic.scope.class}; +any other \grammarterm{lambda-expression} shall not have a \grammarterm{capture-default} or \grammarterm{simple-capture} in its -\grammarterm{lambda-introducer}. The \defn{reaching scope} of a local lambda expression -is the set of enclosing scopes up to and including the innermost enclosing function and -its parameters. \begin{note} This reaching scope includes any intervening -\grammarterm{lambda-expression}{s}. \end{note} +\grammarterm{lambda-introducer}. \pnum The \grammarterm{identifier} in a \grammarterm{simple-capture} is looked up using the usual rules for unqualified name lookup\iref{basic.lookup.unqual}; each such lookup -shall find an entity. An entity that is designated by a +shall find a local entity. +The \grammarterm{simple-capture}{s} \tcode{this} and \tcode{* this} +denote the local entity \tcode{*this}. +An entity that is designated by a \grammarterm{simple-capture} -is said to be \defn{explicitly captured}, and shall be \tcode{*this} -(when the \grammarterm{simple-capture} -is ``\tcode{this}'' or ``\tcode{* this}'') or -a variable with automatic storage duration declared in -the reaching scope of the local lambda expression. +is said to be \defn{explicitly captured}. \pnum If an \grammarterm{identifier} in a \grammarterm{simple-capture} appears @@ -1161,58 +1359,92 @@ \end{example} \pnum -A \grammarterm{lambda-expression} with an associated -\grammarterm{capture-default} that does not explicitly capture \tcode{*this} or -a variable with automatic storage duration (this excludes any \grammarterm{id-expression} -that has been found to refer to an \grammarterm{init-capture}{'s} associated -\indextext{implicit capture!definition of}% -non-static data member), is said to \defnx{implicitly capture}{capture!implicit} -the entity (i.e., -\tcode{*this} or a variable) if the \grammarterm{compound-statement}: +For the purposes of lambda capture, +an expression potentially references local entities as follows: + \begin{itemize} -\item odr-uses\iref{basic.def.odr} the entity (in the case of a variable), -\item odr-uses\iref{basic.def.odr} \tcode{this} -(in the case of the object designated by \tcode{*this}), or -\item names the entity in a potentially-evaluated -expression\iref{basic.def.odr} where the enclosing full-expression depends on -a generic lambda parameter declared within the reaching scope of the -\grammarterm{lambda-expression}. +\item +An \grammarterm{id-expression} that names a local entity +potentially references that entity; +an \grammarterm{id-expression} that names +one or more non-static class members +and does not form a pointer to member\iref{expr.unary.op} +potentially references \tcode{*this}. +\begin{note} +This occurs even if overload resolution +selects a static member function for the \grammarterm{id-expression}. +\end{note} + +\item +A \tcode{this} expression potentially references \tcode{*this}. + +\item +A \grammarterm{lambda-expression} potentially references +the local entities named by its \grammarterm{simple-capture}{s}. \end{itemize} + +If an expression potentially references a local entity +within a declarative region in which it is odr-usable, +and the expression would be potentially evaluated +if the effect of any enclosing \tcode{typeid} expressions\iref{expr.typeid} were ignored, +the entity is said to be \defnx{implicitly captured}{capture!implicit} +by each intervening \grammarterm{lambda-expression} with an associated +\grammarterm{capture-default} that does not explicitly capture it. \begin{example} \begin{codeblock} -void f(int, const int (&)[2] = {}) { } // \#1 -void f(const int&, const int (&)[1]) { } // \#2 +void f(int, const int (&)[2] = {}); // \#1 +void f(const int&, const int (&)[1]); // \#2 void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls \#1, does not capture \tcode{x} }; + auto g1 = [=](auto a) { + f(x); // OK: calls \#1, captures \tcode{x} + }; + auto g2 = [=](auto a) { int selector[sizeof(a) == 1 ? 1 : 2]{}; - f(x, selector); // OK: is a dependent expression, so captures \tcode{x} + f(x, selector); // OK: captures \tcode{x}, might call \#1 or \#2 + }; + + auto g3 = [=](auto a) { + typeid(a + x); // captures \tcode{x} regardless of whether \tcode{a + x} is an unevaluated operand }; } \end{codeblock} +Within \tcode{g1}, an implementation might optimize away +the capture of \tcode{x} as it is not odr-used. +\end{example} +\begin{note} +The set of captured entities is determined syntactically, +and entities might be implicitly captured +even if the expression denoting a local entity +is within a discarded statement\iref{stmt.if}. +\begin{example} +\begin{codeblock} +template +void f(int n) { + [=](auto a) { + if constexpr (B && sizeof(a) > 4) { + (void)n; // captures \tcode{n} regardless of the value of \tcode{B} and \tcode{sizeof(int)} + } + }(0); +} +\end{codeblock} \end{example} -All such implicitly captured -entities shall be declared within the reaching scope of the lambda expression. -\begin{note} The implicit capture of an entity by a nested -\grammarterm{lambda-expression} can cause its implicit capture by the containing -\grammarterm{lambda-expression} (see below). Implicit odr-uses of \tcode{this} can result -in implicit capture. \end{note} +\end{note} \pnum An entity is \defn{captured} if it is captured explicitly or implicitly. An entity captured by a \grammarterm{lambda-expression} is odr-used\iref{basic.def.odr} in the scope -containing the \grammarterm{lambda-expression}. If \tcode{*this} is captured by a local -lambda expression, its nearest enclosing function shall be a non-static member function. -If a \grammarterm{lambda-expression} or an instantiation of the function call -operator template of a generic lambda odr-uses\iref{basic.def.odr} \tcode{this} or a -variable with automatic storage duration from its reaching scope, that -entity shall be captured by the \grammarterm{lambda-expression}. If a -\grammarterm{lambda-expression} captures an entity and that entity is not defined or -captured in the immediately enclosing lambda expression or function, the program is +containing the \grammarterm{lambda-expression}. +If a \grammarterm{lambda-expression} +explicitly captures an entity that is not odr-usable +or +captures a structured binding (explicitly or implicitly), +the program is ill-formed. \begin{example} \indextext{Bond!James Bond}% \begin{codeblock} @@ -1231,10 +1463,11 @@ int m = n*n; int j = 40; auto m3 = [this,m] { - auto m4 = [&,j] { // error: \tcode{j} not captured by \tcode{m3} - int x = n; // error: \tcode{n} implicitly captured by \tcode{m4} but not captured by \tcode{m3} + auto m4 = [&,j] { // error: \tcode{j} not odr-usable due to intervening lambda \tcode{m3} + int x = n; // error: \tcode{n} is odr-used but not odr-usable due to intervening lambda \tcode{m3} x += m; // OK: \tcode{m} implicitly captured by \tcode{m4} and explicitly captured by \tcode{m3} - x += i; // error: \tcode{i} is outside of the reaching scope + x += i; // error: \tcode{i} is odr-used but not odr-usable + // due to intervening function and class scopes x += f; // OK: \tcode{this} captured implicitly by \tcode{m4} and explicitly by \tcode{m3} }; }; @@ -1303,21 +1536,12 @@ entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. \begin{note} An \grammarterm{id-expression} that is not an odr-use refers to -the original entity, never to a member of the closure type. Furthermore, such -an \grammarterm{id-expression} does not cause the implicit capture of the +the original entity, never to a member of the closure type. +However, such +an \grammarterm{id-expression} can still cause the implicit capture of the entity. \end{note} -If \tcode{*this} is captured by copy, each odr-use of \tcode{this} is -transformed into a pointer to the corresponding unnamed data member of the closure type, -cast\iref{expr.cast} to the type of \tcode{this}. \begin{note} The cast ensures that the -transformed expression is a prvalue. \end{note} -An \grammarterm{id-expression} within -the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} -that is an odr-use of a reference captured by reference -refers to the entity to which the captured reference is bound and -not to the captured reference. -\begin{note} The validity of such captures is determined by -the lifetime of the object to which the reference refers, -not by the lifetime of the reference itself. \end{note} +If \tcode{*this} is captured by copy, each expression that odr-uses \tcode{*this} is +transformed to instead refer to the corresponding unnamed data member of the closure type. \begin{example} \begin{codeblock} void f(const int*); @@ -1329,12 +1553,6 @@ // the corresponding member of the closure type }; } -auto h(int &r) { - return [&] { - ++r; // Valid after \tcode{h} returns if the lifetime of the - // object to which \tcode{r} is bound has not ended - }; -} \end{codeblock} \end{example} @@ -1352,6 +1570,26 @@ \end{example} A bit-field or a member of an anonymous union shall not be captured by reference. +\pnum +An \grammarterm{id-expression} within +the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +that is an odr-use of a reference captured by reference +refers to the entity to which the captured reference is bound and +not to the captured reference. +\begin{note} The validity of such captures is determined by +the lifetime of the object to which the reference refers, +not by the lifetime of the reference itself. \end{note} +\begin{example} +\begin{codeblock} +auto h(int &r) { + return [&] { + ++r; // Valid after \tcode{h} returns if the lifetime of the + // object to which \tcode{r} is bound has not ended + }; +} +\end{codeblock} +\end{example} + \pnum If a \grammarterm{lambda-expression} \tcode{m2} captures an entity and that entity is captured by an immediately enclosing \grammarterm{lambda-expression} @@ -1385,26 +1623,6 @@ \end{codeblock} \end{example} -\pnum -Every occurrence of \tcode{decltype((x))} where \tcode{x} is a possibly -parenthesized \grammarterm{id-expression} that names an entity of automatic storage -duration is treated as if \tcode{x} were transformed into an access to a corresponding -data member of the closure type that would have been declared if \tcode{x} were an odr-use of -the denoted entity. \begin{example} - -\begin{codeblock} -void f3() { - float x, &r = x; - [=] { // \tcode{x} and \tcode{r} are not captured (appearance in a \tcode{decltype} operand is not an odr-use) - decltype(x) y1; // \tcode{y1} has type \tcode{float} - decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} because this lambda is not \tcode{mutable} and \tcode{x} is an lvalue - decltype(r) r1 = y1; // \tcode{r1} has type \tcode{float\&} (transformation not considered) - decltype((r)) r2 = y2; // \tcode{r2} has type \tcode{float const\&} - }; -} -\end{codeblock} -\end{example} - \pnum When the \grammarterm{lambda-expression} is evaluated, the entities that are captured by copy are used to direct-initialize each corresponding non-static data member @@ -1520,12 +1738,12 @@ \begin{bnf} \nontermdef{requires-expression}\br - \terminal{requires} requirement-parameter-list\opt{} requirement-body + \terminal{requires} \opt{requirement-parameter-list} requirement-body \end{bnf} \begin{bnf} \nontermdef{requirement-parameter-list}\br - \terminal{(} parameter-declaration-clause\opt{} \terminal{)} + \terminal{(} \opt{parameter-declaration-clause} \terminal{)} \end{bnf} \begin{bnf} @@ -1551,7 +1769,7 @@ A \grammarterm{requires-expression} is a prvalue of type \tcode{bool} whose value is described below. Expressions appearing within a \grammarterm{requirement-body} -are unevaluated operands\iref{expr}. +are unevaluated operands\iref{expr.prop}. \pnum \begin{example} @@ -1649,7 +1867,7 @@ \begin{note} The enclosing \grammarterm{requires-expression} will evaluate to \tcode{false} if substitution of template arguments into the \grammarterm{expression} fails. -The \grammarterm{expression} is an unevaluated operand\iref{expr}. +The \grammarterm{expression} is an unevaluated operand\iref{expr.prop}. \end{note} \begin{example} \begin{codeblock} @@ -1665,7 +1883,7 @@ \begin{bnf} \nontermdef{type-requirement}\br - \terminal{typename} nested-name-specifier\opt type-name \terminal{;} + \terminal{typename} \opt{nested-name-specifier} type-name \terminal{;} \end{bnf} \pnum @@ -1696,13 +1914,13 @@ \begin{bnf} \nontermdef{compound-requirement}\br - \terminal{\{} expression \terminal{\}} \terminal{noexcept}\opt{} return-type-requirement\opt{} \terminal{;} + \terminal{\{} expression \terminal{\}} \opt{\terminal{noexcept}} \opt{return-type-requirement} \terminal{;} \end{bnf} \begin{bnf} \nontermdef{return-type-requirement}\br trailing-return-type\br - \terminal{->} cv-qualifier-seq\opt{} constrained-parameter cv-qualifier-seq\opt{} abstract-declarator\opt{} + \terminal{->} \opt{cv-qualifier-seq} constrained-parameter \opt{cv-qualifier-seq} \opt{abstract-declarator} \end{bnf} \pnum @@ -1836,7 +2054,7 @@ \end{example} \pnum -A local parameter shall only appear as an unevaluated operand\iref{expr} +A local parameter shall only appear as an unevaluated operand\iref{expr.prop} within the \grammarterm{constraint-expression}. \begin{example} \begin{codeblock} @@ -1849,7 +2067,9 @@ \indextext{expression!requires|)} \indextext{expression!primary|)} -\rSec1[expr.post]{Postfix expressions}% +\rSec1[expr.compound]{Compound expressions} + +\rSec2[expr.post]{Postfix expressions}% \indextext{expression!postfix|(} \pnum @@ -1859,13 +2079,13 @@ \nontermdef{postfix-expression}\br primary-expression\br postfix-expression \terminal{[} expr-or-braced-init-list \terminal{]}\br - postfix-expression \terminal{(} expression-list\opt{} \terminal{)}\br - simple-type-specifier \terminal{(} expression-list\opt{} \terminal{)}\br - typename-specifier \terminal{(} expression-list\opt{} \terminal{)}\br + postfix-expression \terminal{(} \opt{expression-list} \terminal{)}\br + simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br + typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br simple-type-specifier braced-init-list\br typename-specifier braced-init-list\br - postfix-expression \terminal{. template}\opt id-expression\br - postfix-expression \terminal{-> template}\opt id-expression\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 @@ -1887,10 +2107,10 @@ \begin{bnf} \nontermdef{pseudo-destructor-name}\br - nested-name-specifier\opt type-name \terminal{::\,\tilde} type-name\br - nested-name-specifier \terminal{template} simple-template-id \terminal{::\,\tilde} type-name\br - \terminal{\tilde} type-name\br - \terminal{\tilde} decltype-specifier + \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 @@ -1901,7 +2121,7 @@ \tcode{>{>}} token by two consecutive \tcode{>} tokens\iref{temp.names}.\end{note} -\rSec2[expr.sub]{Subscripting} +\rSec3[expr.sub]{Subscripting} \pnum \indextext{operator!subscripting}% @@ -1927,7 +2147,7 @@ \pnum A \grammarterm{braced-init-list} shall not be used with the built-in subscript operator. -\rSec2[expr.call]{Function call} +\rSec3[expr.call]{Function call} \pnum \indextext{expression!function call}% @@ -2136,8 +2356,8 @@ An argument that has type \cv{}~\tcode{std::nullptr_t} is converted to type \tcode{void*}\iref{conv.ptr}. After these conversions, if the -argument does not have arithmetic, enumeration, pointer, pointer to -member, or class type, the program is ill-formed. Passing a potentially-evaluated +argument does not have arithmetic, enumeration, pointer, pointer-to-member, +or class type, the program is ill-formed. Passing a potentially-evaluated argument of class type\iref{class} having a non-trivial copy constructor, a non-trivial move constructor, or a @@ -2160,7 +2380,7 @@ an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise. -\rSec2[expr.type.conv]{Explicit type conversion (functional notation)} +\rSec3[expr.type.conv]{Explicit type conversion (functional notation)} \pnum \indextext{expression!cast}% @@ -2181,7 +2401,7 @@ it is replaced by the return type of the function selected by overload resolution for class template deduction\iref{over.match.class.deduct} -for the remainder of this section. +for the remainder of this subclause. \pnum If the initializer is a parenthesized single expression, @@ -2200,7 +2420,7 @@ For an expression of the form \tcode{T()}, \tcode{T} shall not be an array type. -\rSec2[expr.pseudo]{Pseudo destructor call} +\rSec3[expr.pseudo]{Pseudo destructor call} \pnum \indextext{expression!pseudo-destructor call}% @@ -2224,12 +2444,12 @@ the form \begin{ncbnf} -nested-name-specifier\opt type-name \terminal{::\,\tilde} type-name +\opt{nested-name-specifier} type-name \terminal{::\,\~} type-name \end{ncbnf} shall designate the same scalar type (ignoring cv-qualification). -\rSec2[expr.ref]{Class member access} +\rSec3[expr.ref]{Class member access} \pnum \indextext{expression!class member access}% @@ -2337,7 +2557,7 @@ \item Otherwise, if \tcode{E1.E2} refers to a non-static member function and the type of \tcode{E2} is ``function of -parameter-type-list \cvqual{cv} \grammarterm{ref-qualifier}\opt{} returning \tcode{T}'', then +parameter-type-list \cvqual{cv} \opt{\grammarterm{ref-qualifier}} returning \tcode{T}'', then \tcode{E1.E2} is a prvalue. The expression designates a non-static member function. The expression can be used only as the left-hand operand of a member function call\iref{class.mfct}. @@ -2364,7 +2584,7 @@ of the object expression; see~\ref{class.access.base}. \end{note} -\rSec2[expr.post.incr]{Increment and decrement} +\rSec3[expr.post.incr]{Increment and decrement} \pnum \indextext{expression!increment}% @@ -2411,7 +2631,7 @@ For prefix increment and decrement, see~\ref{expr.pre.incr}. \end{note} -\rSec2[expr.dynamic.cast]{Dynamic cast} +\rSec3[expr.dynamic.cast]{Dynamic cast} \pnum \indextext{expression!dynamic cast}% @@ -2486,14 +2706,14 @@ \begin{itemize} \item If, in the most derived object pointed (referred) to by \tcode{v}, -\tcode{v} points (refers) to a \tcode{public} base class subobject of a +\tcode{v} points (refers) to a public base class subobject of a \tcode{C} object, and if only one object of type \tcode{C} is derived from the subobject pointed (referred) to by \tcode{v} the result points (refers) to that \tcode{C} object. -\item Otherwise, if \tcode{v} points (refers) to a \tcode{public} base +\item Otherwise, if \tcode{v} points (refers) to a public base class subobject of the most derived object, and the type of the most derived object has a base class, of type \tcode{C}, that is unambiguous -and \tcode{public}, the result points (refers) to the +and public, the result points (refers) to the \tcode{C} subobject of the most derived object. \item Otherwise, the @@ -2541,7 +2761,7 @@ applied to an object under construction or destruction. \end{note} -\rSec2[expr.typeid]{Type identification} +\rSec3[expr.typeid]{Type identification} \pnum \indextext{expression!type identification}% @@ -2587,7 +2807,7 @@ If the expression is a prvalue, the temporary materialization conversion\iref{conv.rval} is applied. -The expression is an unevaluated operand\iref{expr}. +The expression is an unevaluated operand\iref{expr.prop}. \pnum When \tcode{typeid} is applied to a \grammarterm{type-id}, the result @@ -2628,7 +2848,7 @@ object under construction or destruction. \end{note} -\rSec2[expr.static.cast]{Static cast} +\rSec3[expr.static.cast]{Static cast} \pnum \indextext{expression!static cast}% @@ -2683,7 +2903,7 @@ the result refers to the object or the specified base class subobject thereof; otherwise, the lvalue-to-rvalue conversion\iref{conv.lval} is applied to the bit-field and the resulting prvalue is used as the -\grammarterm{expression} of the \tcode{static_cast} for the remainder of this section. +\grammarterm{expression} of the \tcode{static_cast} for the remainder of this subclause. If \tcode{T2} is an inaccessible\iref{class.access} or ambiguous\iref{class.member.lookup} base class of \tcode{T1}, a program that necessitates such a cast is ill-formed. @@ -2716,7 +2936,7 @@ \pnum Any expression can be explicitly converted to type \cv{}~\tcode{void}, in which case it becomes a discarded-value -expression\iref{expr}. +expression\iref{expr.prop}. \begin{note} However, if the value is in a temporary object\iref{class.temporary}, the destructor for that @@ -2772,9 +2992,16 @@ \indextext{enumeration type!conversion to}% \indextext{enumeration type!\idxcode{static_cast}!conversion to}% A value of integral or enumeration type can be explicitly converted to -a complete enumeration type. The value is unchanged if the original value is -within the range of the enumeration values\iref{dcl.enum}. Otherwise, -the behavior is undefined. +a complete enumeration type. +If the enumeration type has a fixed underlying type, +the value is first converted to that type +by integral conversion, if necessary, and +then to the enumeration type. +If the enumeration type does not have a fixed underlying type, +the value is unchanged +if the original value is within the range +of the enumeration values\iref{dcl.enum}, and +otherwise, the behavior is undefined. A value of floating-point type can also be explicitly converted to an enumeration type. The resulting value is the same as converting the original value to the underlying type of the enumeration\iref{conv.fpint}, and subsequently to @@ -2808,7 +3035,7 @@ class\iref{class.derived} of \tcode{D}, if \cvqual{cv2} is the same cv-qualification as, or greater cv-qualification than, \cvqual{cv1}.\footnote{Function types -(including those used in pointer to member function +(including those used in pointer-to-member-function types) are never cv-qualified; see~\ref{dcl.fct}.} If no valid standard conversion from ``pointer to member of \tcode{B} of type \tcode{T}'' @@ -2849,7 +3076,7 @@ \end{codeblock} \end{example} -\rSec2[expr.reinterpret.cast]{Reinterpret cast} +\rSec3[expr.reinterpret.cast]{Reinterpret cast} \pnum \indextext{expression!reinterpret cast}% @@ -2979,35 +3206,35 @@ \begin{itemize} \item converting a prvalue of type ``pointer to member function'' to a -different pointer to member function type and back to its original type -yields the original pointer to member value. +different pointer-to-member-function type and back to its original type +yields the original pointer-to-member value. \item converting a prvalue of type ``pointer to data member of \tcode{X} of type \tcode{T1}'' to the type ``pointer to data member of \tcode{Y} of type \tcode{T2}'' (where the alignment requirements of \tcode{T2} are no stricter than those of \tcode{T1}) and back to its original type -yields the original pointer to member value. +yields the original pointer-to-member value. \end{itemize} \pnum \indextext{cast!reinterpret!reference}% \indextext{cast!reference}% -A glvalue expression of type \tcode{T1} can be cast to the type -``reference to \tcode{T2}'' if an expression of type ``pointer to -\tcode{T1}'' can be explicitly converted to the type ``pointer to -\tcode{T2}'' using a \tcode{reinterpret_cast}. The result refers to -the same object as the source glvalue, but with the specified -type. \begin{note} That is, for lvalues, a reference cast -\tcode{reinterpret_cast(x)} has the same effect as the conversion -\tcode{*reinterpret_cast(\&x)} with the built-in \tcode{\&} and -\tcode{*} operators (and similarly for -\tcode{reinterpret_cast(x)}). \end{note} No -temporary is created, no copy is made, and -constructors\iref{class.ctor} or conversion -functions\iref{class.conv} are not called.\footnote{This -is sometimes referred to as a \defn{type pun}.} - -\rSec2[expr.const.cast]{Const cast} +A glvalue expression of type \tcode{T1}, +designating an object \placeholder{x}, +can be cast to the type ``reference to \tcode{T2}'' +if an expression of type ``pointer to \tcode{T1}'' +can be explicitly converted to the type ``pointer to \tcode{T2}'' +using a \tcode{reinterpret_cast}. +The result is that of \tcode{*reinterpret_cast(p)} +where \tcode{p} is a pointer to \placeholder{x} +of type ``pointer to \tcode{T1}''. +No temporary is created, no copy is made, and +no constructors\iref{class.ctor} or conversion +functions\iref{class.conv} are called.% +\footnote{This is sometimes referred to as a \defn{type pun} +when the result refers to the same object as the source glvalue.} + +\rSec3[expr.const.cast]{Const cast} \pnum \indextext{expression!const cast}% @@ -3025,7 +3252,7 @@ \pnum \begin{note} -Subject to the restrictions in this section, an expression may be cast +Subject to the restrictions in this subclause, an expression may be cast to its own type using a \tcode{const_cast} operator. \end{note} @@ -3121,7 +3348,7 @@ \end{note}% \indextext{expression!postfix|)} -\rSec1[expr.unary]{Unary expressions} +\rSec2[expr.unary]{Unary expressions} \pnum \indextext{expression!unary|(}% @@ -3158,16 +3385,16 @@ \indextext{operator!logical negation}% \indextext{\idxcode{"!}|see{operator, logical negation}}% \indextext{operator!ones' complement}% -\indextext{~@\tcode{\tilde}|see{operator, ones' complement}}% +\indextext{~@\tcode{\~}|see{operator, ones' complement}}% \indextext{operator!increment}% \indextext{operator!decrement}% % \begin{bnf} \nontermdef{unary-operator} \textnormal{one of}\br - \terminal{* \& + - ! \tilde} + \terminal{* \& + - ! \~} \end{bnf} -\rSec2[expr.unary.op]{Unary operators} +\rSec3[expr.unary.op]{Unary operators} \pnum \indextext{expression!unary operator}% @@ -3192,7 +3419,7 @@ \pnum \indextext{name!address of cv-qualified}% -\indextext{expression!pointer to member constant}% +\indextext{expression!pointer-to-member constant}% The result of the unary \tcode{\&} operator is a pointer to its operand. The operand shall be an lvalue or a \grammarterm{qualified-id}. If the operand is a \grammarterm{qualified-id} naming a non-static or variant member \tcode{m} @@ -3304,7 +3531,7 @@ unambiguously parsed as a destructor name. \end{note} -\rSec2[expr.pre.incr]{Increment and decrement} +\rSec3[expr.pre.incr]{Increment and decrement} \pnum \indextext{expression!increment}% @@ -3337,7 +3564,7 @@ For postfix increment and decrement, see~\ref{expr.post.incr}. \end{note} -\rSec2[expr.sizeof]{Sizeof} +\rSec3[expr.sizeof]{Sizeof} \pnum \indextext{expression!\idxcode{sizeof}}% @@ -3345,7 +3572,7 @@ \indextext{byte}% The \tcode{sizeof} operator yields the number of bytes in the object representation of its operand. The operand is either an expression, -which is an unevaluated operand\iref{expr}, or a parenthesized +which is an unevaluated operand\iref{expr.prop}, or a parenthesized \grammarterm{type-id}. \indextext{type!incomplete}% The \tcode{sizeof} operator shall not be applied to an expression that @@ -3421,11 +3648,11 @@ \indextext{\idxcode{size_t}}% \indexlibrary{\idxcode{size_t}}% \tcode{std::size_t} is defined in the standard header -\indextext{\idxhdr{cstddef}}% +\indexhdr{cstddef}% \tcode{}~(\ref{cstddef.syn}, \ref{support.types.layout}). \end{note} -\rSec2[expr.new]{New} +\rSec3[expr.new]{New} \pnum \indextext{expression!\idxcode{new}}% @@ -3451,8 +3678,8 @@ \begin{bnf} \nontermdef{new-expression}\br - \terminal{::}\opt{} \terminal{new} new-placement\opt new-type-id new-initializer\opt \br - \terminal{::}\opt{} \terminal{new} new-placement\opt{} \terminal{(} type-id \terminal{)} new-initializer\opt + \opt{\terminal{::}} \terminal{new} \opt{new-placement} new-type-id \opt{new-initializer} \br + \opt{\terminal{::}} \terminal{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer} \end{bnf} \indextext{\idxcode{new}!storage allocation}% @@ -3464,24 +3691,24 @@ \begin{bnf} \nontermdef{new-type-id}\br - type-specifier-seq new-declarator\opt + type-specifier-seq \opt{new-declarator} \end{bnf} \begin{bnf} \nontermdef{new-declarator}\br - ptr-operator new-declarator\opt \br + ptr-operator \opt{new-declarator} \br noptr-new-declarator \end{bnf} \begin{bnf} \nontermdef{noptr-new-declarator}\br - \terminal{[} expression \terminal{]} attribute-specifier-seq\opt\br - noptr-new-declarator \terminal{[} constant-expression \terminal{]} attribute-specifier-seq\opt + \terminal{[} expression \terminal{]} \opt{attribute-specifier-seq}\br + noptr-new-declarator \terminal{[} constant-expression \terminal{]} \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} \nontermdef{new-initializer}\br - \terminal{(} expression-list\opt{} \terminal{)}\br + \terminal{(} \opt{expression-list} \terminal{)}\br braced-init-list \end{bnf} @@ -3493,9 +3720,9 @@ The lifetime of such an entity is not necessarily restricted to the scope in which it is created. \end{note} -If the entity is a non-array object, the \grammarterm{new-expression} -returns a pointer to the object created. If it is an array, the -\grammarterm{new-expression} returns a pointer to the initial element of +If the entity is a non-array object, the result of the \grammarterm{new-expression} +is a pointer to the object created. If it is an array, the result of the +\grammarterm{new-expression} is a pointer to the initial element of the array. \pnum @@ -3672,7 +3899,7 @@ An implementation shall provide default definitions for the global allocation functions~(\ref{basic.stc.dynamic}, \ref{new.delete.single}, \ref{new.delete.array}). -A \Cpp program can provide alternative definitions of +A \Cpp{} program can provide alternative definitions of these functions\iref{replacement.functions} and/or class-specific versions\iref{class.free}. The set of allocation and deallocation functions that may be called @@ -3971,14 +4198,14 @@ argument of type \tcode{void*}. If a placement deallocation function is called, it is passed the same additional arguments as were passed to the placement allocation function, that is, the same arguments as those -specified with the \grammarterm{new-placement} syntax. If the -implementation is allowed to make a copy of any argument as part of the -call to the allocation function, it is allowed to make a copy (of the -same original value) as part of the call to the deallocation function or -to reuse the copy made as part of the call to the allocation function. -If the copy is elided in one place, it need not be elided in the other. +specified with the \grammarterm{new-placement} syntax. +If the implementation is allowed +to introduce a temporary object or make a copy of any argument +as part of the call to the allocation function, +it is unspecified whether the same object is used in the call +to both the allocation and deallocation functions. -\rSec2[expr.delete]{Delete} +\rSec3[expr.delete]{Delete} \pnum \indextext{expression!\idxcode{delete}}% @@ -3989,15 +4216,17 @@ \begin{bnf} \nontermdef{delete-expression}\br - \terminal{::}\opt{} \terminal{delete} cast-expression\br - \terminal{::}\opt{} \terminal{delete [ ]} cast-expression + \opt{\terminal{::}} \terminal{delete} cast-expression\br + \opt{\terminal{::}} \terminal{delete [ ]} cast-expression \end{bnf} -The first alternative is for non-array objects, and the second is for arrays. Whenever -the \tcode{delete} keyword is immediately followed by empty square brackets, it shall be -interpreted as the second alternative.\footnote{A lambda expression with a -\grammarterm{lambda-introducer} that consists of -empty square brackets can follow the \tcode{delete} keyword if the lambda expression is +The first alternative is a +\defnx{single-object delete expression}{delete!single-object}, and the +second is an \defnx{array delete expression}{delete!array}. +Whenever the \tcode{delete} keyword is immediately followed by empty square +brackets, it shall be interpreted as the second alternative.\footnote{A lambda +expression with a \grammarterm{lambda-introducer} that consists of empty square +brackets can follow the \tcode{delete} keyword if the lambda expression is enclosed in parentheses.} The operand shall be of pointer to object type or of class type. If of class type, the operand is contextually implicitly converted\iref{conv} @@ -4009,23 +4238,20 @@ \tcode{void}. \pnum -\indextext{\idxcode{delete}!object}% +\indextext{\idxcode{delete}!single-object}% If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the -remainder of this section. -In the first alternative -(\defnx{delete object}{object!delete}), the value of the operand of \tcode{delete} may -be a null pointer value, a pointer to a non-array object +remainder of this subclause. +In a single-object delete expression, the value of the operand of +\tcode{delete} may be a null pointer value, a pointer to a non-array object created by a previous \grammarterm{new-expression}, or a pointer to a subobject\iref{intro.object} representing a base class of such an object\iref{class.derived}. If not, the behavior is undefined. \indextext{array!\idxcode{delete}}% -In the second alternative (\defnx{delete array}{\idxcode{delete}!array}), the value of the -operand of \tcode{delete} -may be a null pointer value or a pointer value -that resulted from +In an array delete expression, the value of the operand of \tcode{delete} +may be a null pointer value or a pointer value that resulted from a previous array \grammarterm{new-expression}.\footnote{For nonzero-length arrays, this is the same as a pointer to the first element of the array created by that \grammarterm{new-expression}. @@ -4045,12 +4271,12 @@ \pnum \indextext{\idxcode{delete}!undefined}% -In the first alternative (\term{delete object}), if the static type of -the object to be deleted is different from its dynamic type, the static type shall be -a base class of the dynamic type of the object to be deleted and the static type shall -have a virtual destructor or the behavior is undefined. In the second -alternative (\term{delete array}) if the dynamic type of the object to -be deleted differs from its static type, the behavior is undefined. +In a single-object delete expression, if the static type of the object to be +deleted is different from its dynamic type, the static type shall be a base +class of the dynamic type of the object to be deleted and the static type shall +have a virtual destructor or the behavior is undefined. In an array delete +expression, if the dynamic type of the object to be deleted differs from its +static type, the behavior is undefined. \pnum The \grammarterm{cast-expression} in a \grammarterm{delete-expression} shall @@ -4112,7 +4338,7 @@ deallocation functions \tcode{operator delete} for non-arrays\iref{new.delete.single} and \indextext{\idxcode{operator delete}}% -\tcode{operator delete[]} for arrays\iref{new.delete.array}. A \Cpp +\tcode{operator delete[]} for arrays\iref{new.delete.array}. A \Cpp{} program can provide alternative definitions of these functions\iref{replacement.functions}, and/or class-specific versions\iref{class.free}. @@ -4155,9 +4381,9 @@ \pnum When a \grammarterm{delete-expression} is executed, the selected deallocation function shall be called with -the address of the most-derived object in the \term{delete object} case, or -the address of the object suitably adjusted for -the array allocation overhead\iref{expr.new} in the \term{delete array} case, +the address of the most-derived object in a single-object delete expression, or +the address of the object suitably adjusted for the array allocation +overhead\iref{expr.new} in an array delete expression, as its first argument. If a deallocation function with a parameter of type \tcode{std::align_val_t} @@ -4185,7 +4411,7 @@ Access and ambiguity control are done for both the deallocation function and the destructor~(\ref{class.dtor}, \ref{class.free}). -\rSec2[expr.alignof]{Alignof} +\rSec3[expr.alignof]{Alignof} \pnum \indextext{\idxcode{alignof}}% @@ -4205,13 +4431,13 @@ is applied to an array type, the result is the alignment of the element type. -\rSec2[expr.unary.noexcept]{\tcode{noexcept} operator} +\rSec3[expr.unary.noexcept]{\tcode{noexcept} operator} \pnum \indextext{\idxcode{noexcept}}% \indextext{expression!\idxcode{noexcept}}% The \tcode{noexcept} operator determines whether the evaluation of its operand, -which is an unevaluated operand\iref{expr}, can throw an +which is an unevaluated operand\iref{expr.prop}, can throw an exception\iref{except.throw}. \begin{bnf} @@ -4228,7 +4454,7 @@ unless the \grammarterm{expression} is potentially-throwing\iref{except.spec}. \indextext{expression!unary|)} -\rSec1[expr.cast]{Explicit type conversion (cast notation)}% +\rSec2[expr.cast]{Explicit type conversion (cast notation)}% \indextext{expression!cast|(} \pnum @@ -4239,7 +4465,7 @@ \begin{note} If \tcode{T} is a non-class type that is cv-qualified, the \grammarterm{cv-qualifier}{s} are discarded when determining the type of the -resulting prvalue; see \ref{expr}. +resulting prvalue; see \ref{expr.prop}. \end{note} \pnum @@ -4329,7 +4555,7 @@ \end{note}% \indextext{expression!cast|)} -\rSec1[expr.mptr.oper]{Pointer-to-member operators} +\rSec2[expr.mptr.oper]{Pointer-to-member operators} \pnum \indextext{expression!pointer-to-member}% @@ -4382,7 +4608,7 @@ \tcode{E1.E2} given in~\ref{expr.ref}. \begin{note} It is not possible to use a pointer to member that refers to a -\tcode{mutable} member to modify a \tcode{const} class object. For +\tcode{mutable} member to modify a const class object. For example, \begin{codeblock} @@ -4394,7 +4620,7 @@ { const S cs; int S::* pm = &S::i; // \tcode{pm} refers to \tcode{mutable} member \tcode{S::i} -cs.*pm = 88; // ill-formed: \tcode{cs} is a \tcode{const} object +cs.*pm = 88; // ill-formed: \tcode{cs} is a const object } \end{codeblock} \end{note} @@ -4429,7 +4655,7 @@ If the second operand is the null member pointer value\iref{conv.mem}, the behavior is undefined. -\rSec1[expr.mul]{Multiplicative operators}% +\rSec2[expr.mul]{Multiplicative operators}% \indextext{expression!multiplicative operators}% \indextext{operator!multiplicative} @@ -4456,7 +4682,7 @@ \pnum The operands of \tcode{*} and \tcode{/} shall have arithmetic or unscoped enumeration type; the operands of \tcode{\%} shall have integral or unscoped -enumeration type. The usual arithmetic conversions are performed on the +enumeration type. The usual arithmetic conversions\iref{expr.arith.conv} are performed on the operands and determine the type of the result. \pnum @@ -4475,13 +4701,13 @@ \tcode{(a/b)*b + a\%b} is equal to \tcode{a}; otherwise, the behavior of both \tcode{a/b} and \tcode{a\%b} is undefined. -\rSec1[expr.add]{Additive operators}% +\rSec2[expr.add]{Additive operators}% \indextext{expression!additive operators}% \indextext{operator!additive} \pnum The additive operators \tcode{+} and \tcode{-} group left-to-right. The -usual arithmetic conversions are performed for operands of arithmetic or +usual arithmetic conversions\iref{expr.arith.conv} are performed for operands of arithmetic or enumeration type. \indextext{operator!addition}% @@ -4547,7 +4773,7 @@ \indextext{\idxcode{ptrdiff_t}!implementation-defined type of}% \indextext{subtraction!implementation-defined pointer}% \indextext{\idxcode{ptrdiff_t}}% -\indextext{\idxhdr{cstddef}}% +\indexhdr{cstddef}% \indextext{comparison!undefined pointer}% When two pointers to elements of the same array object are subtracted, the type of the result is an \impldef{type of \tcode{ptrdiff_t}} signed @@ -4585,7 +4811,7 @@ the result compares equal to the value 0 converted to the type \tcode{std::ptrdiff_t}. -\rSec1[expr.shift]{Shift operators} +\rSec2[expr.shift]{Shift operators} \pnum \indextext{expression!left-shift-operator}% @@ -4637,7 +4863,153 @@ \pnum The expression \tcode{E1} is sequenced before the expression \tcode{E2}. -\rSec1[expr.rel]{Relational operators}% +\rSec2[expr.spaceship]{Three-way comparison operator} +\indextext{expression!three-way comparison}% +\indextext{expression!spaceship}% + +\pnum +The three-way comparison operator groups left-to-right. + +\indextext{\idxcode{<=>}|see{operator, three-way comparison}}% +\indextext{operator!three-way comparison}% +\indextext{operator!spaceship}% + +\begin{bnf} +\nontermdef{compare-expression}\br + shift-expression\br + compare-expression \terminal{<=>} shift-expression +\end{bnf} + +\pnum +The expression \tcode{p <=> q} is a prvalue indicating whether +\tcode{p} is less than, equal to, greater than, or incomparable with +\tcode{q}. + +\pnum +If one of the operands is of type \tcode{bool} +and the other is not, the program is ill-formed. + +\pnum +If both operands have arithmetic types, +the usual arithmetic conversions\iref{expr.arith.conv} are applied to the operands. +Then: + +\begin{itemize} +\item +If a narrowing conversion\iref{dcl.init.list} is required, +other than from an integral type to a floating point type, +the program is ill-formed. + +\item +Otherwise, if the operands have integral type, +the result is of type \tcode{std::strong_ordering}. +The result is +\tcode{std::strong_ordering::equal} +if both operands are arithmetically equal, +\tcode{std::strong_ordering::less} +if the first operand is arithmetically +less than the second operand, +and +\tcode{std::strong_ordering::greater} +otherwise. +\item +Otherwise, the operands have floating-point type, and +the result is of type \tcode{std::partial_ordering}. +The expression \tcode{a <=> b} yields +\tcode{std::partial_ordering::less} +if \tcode{a} is less than \tcode{b}, +\tcode{std::partial_ordering::greater} +if \tcode{a} is greater than \tcode{b}, +\tcode{std::partial_ordering::equivalent} +if \tcode{a} is equivalent to \tcode{b}, +and +\tcode{std::partial_ordering::unordered} otherwise. +\end{itemize} + +\pnum +If both operands have the same enumeration type \tcode{E}, +the operator yields the result of +converting the operands to the underlying type of \tcode{E} +and applying \tcode{<=>} to the converted operands. + +\pnum +If at least one of the operands is of pointer type, +array-to-pointer conversions\iref{conv.array}, +pointer conversions\iref{conv.ptr}, +function pointer conversions\iref{conv.fctptr}, +and +qualification conversions\iref{conv.qual} +are performed on both operands +to bring them to their composite pointer type\iref{expr.type}. +% +If at least one of the operands is of pointer-to-member type, +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.type}. +% +If both operands are null pointer constants, +but not both of integer type, +pointer conversions\iref{conv.ptr} +are performed on both operands +to bring them to their composite pointer type\iref{expr.type}. +% +In all cases, after the conversions, the operands shall have the same type. +\begin{note} +If both of the operands are arrays, +array-to-pointer conversions\iref{conv.array} are not applied. +\end{note} + +\pnum +If the composite pointer type is +a function pointer type, +a pointer-to-member type, or +\tcode{std::nullptr_t}, +the result is of type \tcode{std::strong_equality}; +the result is +\tcode{std::strong_equality::equal} +if the (possibly converted) operands compare equal\iref{expr.eq} +and +\tcode{std::strong_equality::unequal} +if they compare unequal, +otherwise the result of the operator is unspecified. + +\pnum +If the composite pointer type is an object pointer type, +\tcode{p <=> q} is of type \tcode{std::strong_ordering}. +If two pointer operands \tcode{p} and \tcode{q} compare equal\iref{expr.eq}, +\tcode{p <=> q} yields \tcode{std::strong_ordering::equal}; +if \tcode{p} and \tcode{q} compare unequal, +\tcode{p <=> q} yields +\tcode{std::strong_ordering::less} +if \tcode{q} compares greater than \tcode{p} +and +\tcode{std::strong_ordering::greater} +if \tcode{p} compares greater than \tcode{q}\iref{expr.rel}. +Otherwise, the result is unspecified. + +\pnum +Otherwise, the program is ill-formed. + +\pnum +The five comparison category types\iref{cmp.categories} +(the types +\tcode{std::strong_ordering}, +\tcode{std::strong_equality}, +\tcode{std::weak_ordering}, +\tcode{std::weak_equality}, and +\tcode{std::partial_ordering}) +are not predefined; +if the header +\indexhdr{compare}\tcode{} +is not included prior to a use of such a class type -- +even an implicit use in which the type is not named +(e.g., via the \tcode{auto} specifier\iref{dcl.spec.auto} +in a defaulted three-way comparison\iref{class.spaceship} +or use of the built-in operator) -- the program is ill-formed. + +\rSec2[expr.rel]{Relational operators}% \indextext{expression!relational operators}% \indextext{operator!relational} @@ -4659,11 +5031,11 @@ % \begin{bnf} \nontermdef{relational-expression}\br - shift-expression\br - relational-expression \terminal{<} shift-expression\br - relational-expression \terminal{>} shift-expression\br - relational-expression \terminal{<=} shift-expression\br - relational-expression \terminal{>=} shift-expression + compare-expression\br + relational-expression \terminal{<} compare-expression\br + relational-expression \terminal{>} compare-expression\br + relational-expression \terminal{<=} compare-expression\br + relational-expression \terminal{>=} compare-expression \end{bnf} The operands shall have arithmetic, enumeration, or pointer type. The @@ -4673,11 +5045,11 @@ \tcode{bool}. \pnum -The usual arithmetic conversions are performed on operands of arithmetic +The usual arithmetic conversions\iref{expr.arith.conv} are performed on operands of arithmetic 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}. +them to their composite pointer type\iref{expr.prop}. After conversions, the operands shall have the same type. \pnum @@ -4719,7 +5091,7 @@ of the operators shall yield \tcode{true} if the specified relationship is true and \tcode{false} if it is false. -\rSec1[expr.eq]{Equality operators}% +\rSec2[expr.eq]{Equality operators}% \indextext{expression!equality operators}% \indextext{operator!equality}% \indextext{operator!inequality} @@ -4734,7 +5106,7 @@ \pnum The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators group left-to-right. The operands shall have arithmetic, enumeration, pointer, -or pointer to member type, or type \tcode{std::nullptr_t}. The operators +or pointer-to-member type, or type \tcode{std::nullptr_t}. The operators \tcode{==} and \tcode{!=} both yield \tcode{true} or \tcode{false}, i.e., a result of type \tcode{bool}. In each case below, the operands shall have the same type after the specified conversions have been applied. @@ -4746,7 +5118,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}. +are performed on both operands to bring them to their composite pointer type\iref{expr.prop}. Comparing pointers is defined as follows: \begin{itemize} @@ -4766,10 +5138,10 @@ \end{itemize} \pnum -If at least one of the operands is a pointer to member, pointer to member +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}. +their composite pointer type\iref{expr.prop}. Comparing pointers to members is defined as follows: \begin{itemize} @@ -4844,11 +5216,11 @@ \pnum If both operands are of arithmetic or enumeration type, the usual arithmetic -conversions are performed on both operands; each of the operators shall yield +conversions\iref{expr.arith.conv} are performed on both operands; each of the operators shall yield \tcode{true} if the specified relationship is true and \tcode{false} if it is false. -\rSec1[expr.bit.and]{Bitwise AND operator}% +\rSec2[expr.bit.and]{Bitwise AND operator}% \indextext{expression!bitwise AND}% \indextext{operator!bitwise}% \indextext{operator!bitwise AND}% @@ -4861,11 +5233,11 @@ \end{bnf} \pnum -The usual arithmetic conversions are performed; the result is the +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. -\rSec1[expr.xor]{Bitwise exclusive OR operator}% +\rSec2[expr.xor]{Bitwise exclusive OR operator}% \indextext{expression!bitwise exclusive OR}% \indextext{operator!bitwise exclusive OR}% \indextext{\idxcode{\caret}|see{operator, bitwise exclusive OR}} @@ -4877,11 +5249,11 @@ \end{bnf} \pnum -The usual arithmetic conversions are performed; the result is the +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. -\rSec1[expr.or]{Bitwise inclusive OR operator}% +\rSec2[expr.or]{Bitwise inclusive OR operator}% \indextext{expression!bitwise inclusive OR}% \indextext{operator!bitwise inclusive OR}% \indextext{\idxcode{"|}|see{operator, bitwise inclusive OR}} @@ -4893,11 +5265,11 @@ \end{bnf} \pnum -The usual arithmetic conversions are performed; the result is the +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. -\rSec1[expr.log.and]{Logical AND operator}% +\rSec2[expr.log.and]{Logical AND operator}% \indextext{expression!logical AND}% \indextext{operator!logical AND}% \indextext{\idxcode{\&\&}|see{operator, logical AND}}% @@ -4928,7 +5300,7 @@ effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression. -\rSec1[expr.log.or]{Logical OR operator}% +\rSec2[expr.log.or]{Logical OR operator}% \indextext{expression!logical OR}% \indextext{operator!logical OR}% \indextext{\idxcode{"|"|}|see{operator, logical OR}}% @@ -4942,7 +5314,7 @@ \pnum The \tcode{||} operator groups left-to-right. The operands are both contextually converted to \tcode{bool}\iref{conv}. -It returns +The result is \tcode{true} if either of its operands is \tcode{true}, and \tcode{false} otherwise. Unlike \tcode{|}, \tcode{||} guarantees left-to-right evaluation; moreover, the second operand is not evaluated @@ -4959,7 +5331,7 @@ associated with the first expression is sequenced before every value computation and side effect associated with the second expression. -\rSec1[expr.cond]{Conditional operator}% +\rSec2[expr.cond]{Conditional operator}% \indextext{expression!conditional operator}% \indextext{operator!conditional expression}% \indextext{\idxcode{?:}|see{operator, conditional expression}}% @@ -5006,7 +5378,7 @@ of the same value category and of types \cvqual{cv1} \tcode{T} and \cvqual{cv2} \tcode{T}, respectively, the operands are considered to be of type \cvqual{cv} \tcode{T} -for the remainder of this section, +for the remainder of this subclause, where \cvqual{cv} is the union of \cvqual{cv1} and \cvqual{cv2}. \pnum @@ -5063,7 +5435,7 @@ Otherwise, if exactly one conversion sequence can be formed, that conversion is applied to the chosen operand and the converted operand is used in place of the original operand for -the remainder of this section. +the remainder of this subclause. \begin{note} The conversion might be ill-formed even if an implicit conversion sequence could be formed. @@ -5083,7 +5455,7 @@ If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this -section. +subclause. \pnum Lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, @@ -5096,7 +5468,7 @@ that type and the result object is initialized using the selected operand. \item The second and third operands have arithmetic or enumeration type; -the usual arithmetic conversions are performed to bring them to a common +the usual arithmetic conversions\iref{expr.arith.conv} are performed to bring them to a common type, and the result is of that type. \item One or both of the second and third operands have pointer type; @@ -5104,13 +5476,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}. The result is of the composite +composite pointer type\iref{expr.prop}. The result is of the composite pointer type. -\item One or both of the second and third operands have pointer to member 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}. The result is of the composite pointer type. +pointer type\iref{expr.prop}. The result is of the composite pointer type. \item Both the second and third operands have type \tcode{std::nullptr_t} or one has @@ -5119,14 +5491,14 @@ \end{itemize} -\rSec1[expr.throw]{Throwing an exception}% +\rSec2[expr.throw]{Throwing an exception}% \indextext{expression!\idxcode{throw}}% \indextext{exception handling!throwing}% \indextext{\idxcode{throw}}% % \begin{bnf} \nontermdef{throw-expression}\br - \terminal{throw} assignment-expression\opt + \terminal{throw} \opt{assignment-expression} \end{bnf} \pnum @@ -5171,7 +5543,7 @@ with no operand calls \tcode{std::\brk{}terminate()}\iref{except.terminate}. -\rSec1[expr.ass]{Assignment and compound assignment operators}% +\rSec2[expr.ass]{Assignment and compound assignment operators}% \indextext{expression!assignment and compound assignment} \pnum @@ -5191,7 +5563,7 @@ operators all group right-to-left. \indextext{assignment!and lvalue}% All -require a modifiable lvalue as their left operand and return an lvalue +require a modifiable lvalue as their left operand; their result is an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the @@ -5291,7 +5663,7 @@ \end{codeblock} \end{example} -\rSec1[expr.comma]{Comma operator}% +\rSec2[expr.comma]{Comma operator}% \indextext{expression!comma}% \indextext{operator!comma}% \indextext{comma operator|see{operator, comma}}% @@ -5309,7 +5681,7 @@ A pair of expressions separated by a comma is evaluated left-to-right; the left expression is -a discarded-value expression\iref{expr}. +a discarded-value expression\iref{expr.prop}. Every \indextext{value computation}% value computation and side effect @@ -5327,7 +5699,7 @@ In contexts where comma is given a special meaning, \begin{example} in lists of arguments to functions\iref{expr.call} and lists of initializers\iref{dcl.init} \end{example} the comma operator as -described in \ref{expr} can appear only in parentheses. +described in this subclause can appear only in parentheses. \begin{example} \begin{codeblock} @@ -5395,7 +5767,7 @@ an operation that would have undefined behavior as specified in \ref{intro} through \ref{cpp} of this document \begin{note} including, -for example, signed integer overflow\iref{expr}, certain +for example, signed integer overflow\iref{expr.prop}, certain pointer arithmetic\iref{expr.add}, division by zero\iref{expr.mul}, or certain shift operations\iref{expr.shift} \end{note}; @@ -5519,6 +5891,11 @@ \item a \grammarterm{delete-expression}\iref{expr.delete}; +\item +a three-way comparison\iref{expr.spaceship} +comparing pointers that do not point to the same +complete object or to any subobject thereof; + \item a relational\iref{expr.rel} or equality\iref{expr.eq} operator where the result is unspecified; or @@ -5690,4 +6067,51 @@ \end{codeblock} It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}. \end{example} \end{note}% + +\pnum +\indextext{expression!potentially constant evaluated}% +An expression is \defn{potentially constant evaluated} +if it is: + +\begin{itemize} +\item +a potentially-evaluated expression\iref{basic.def.odr}, + +\item +a \grammarterm{constraint-expression}, +including one formed from the \grammarterm{constraint-logical-or-expression} +of a \grammarterm{requires-clause}, + +\item +an immediate subexpression of a \grammarterm{braced-init-list},% +\footnote{Constant evaluation may be necessary to determine whether a narrowing conversion is performed\iref{dcl.init.list}.} + +\item +an expression of the form \tcode{\&} \grammarterm{cast-expression} +that occurs within a templated entity,% +\footnote{Constant evaluation may be necessary to determine whether such an expression is value-dependent\iref{temp.dep.constexpr}.} +or + +\item +a subexpression of one of the above +that is not a subexpression of a nested unevaluated operand. +\end{itemize} + +\indextext{function!needed for constant evaluation}% +\indextext{variable!needed for constant evaluation}% +A function or variable is +\defn{needed for constant evaluation} +if it is: + +\begin{itemize} +\item +a constexpr function that is named by an expression\iref{basic.def.odr} +that is potentially constant evaluated, or + +\item +a variable whose name appears as a potentially constant evaluated expression +that is either a constexpr variable or +is of non-volatile const-qualified integral type or of reference type. +\end{itemize} + \indextext{expression|)} diff --git a/source/future.tex b/source/future.tex index b770fcad99..72c7630fae 100644 --- a/source/future.tex +++ b/source/future.tex @@ -2,7 +2,7 @@ \normannex{depr}{Compatibility features} \pnum -This Clause describes features of the \Cpp Standard that are specified for compatibility with +This Clause describes features of the \Cpp{} Standard that are specified for compatibility with existing implementations. \pnum @@ -11,7 +11,7 @@ is defined as: Normative for the current edition of this International Standard, but having been identified as a candidate for removal from future revisions. -An implementation may declare library names and entities described in this section with the +An implementation may declare library names and entities described in this Clause with the \tcode{deprecated} attribute\iref{dcl.attr.deprecated}. \rSec1[depr.static_constexpr]{Redeclaration of \tcode{static constexpr} data members} @@ -23,10 +23,10 @@ \begin{example} \begin{codeblock} struct A { - static constexpr int n = 5; // definition (declaration in \CppXIV) + static constexpr int n = 5; // definition (declaration in \CppXIV{}) }; -constexpr int A::n; // redundant declaration (definition in \CppXIV) +constexpr int A::n; // redundant declaration (definition in \CppXIV{}) \end{codeblock} \end{example} @@ -48,11 +48,11 @@ \pnum The \grammarterm{noexcept-specifier} \tcode{throw()} is deprecated. -\rSec1[depr.cpp.headers]{\Cpp standard library headers} +\rSec1[depr.cpp.headers]{\Cpp{} standard library headers} \pnum -For compatibility with prior \Cpp International Standards, -the \Cpp standard library provides headers +For compatibility with prior \Cpp{} International Standards, +the \Cpp{} standard library provides headers \tcode{}\iref{depr.ccomplex.syn}, \tcode{}\iref{depr.cstdalign.syn}, \tcode{}\iref{depr.cstdbool.syn}, @@ -60,7 +60,7 @@ The use of these headers is deprecated. \rSec2[depr.ccomplex.syn]{Header \tcode{} synopsis} -\indexlibrary{\idxhdr{ccomplex}}% +\indexhdr{ccomplex}% \begin{codeblock} #include @@ -74,14 +74,14 @@ \rSec2[depr.cstdalign.syn]{Header \tcode{} synopsis} \indexlibrary{\idxcode{__alignas_is_defined}}% -\indexlibrary{\idxhdr{cstdalign}}% +\indexhdr{cstdalign}% \begin{codeblock} #define @\xname{alignas_is_defined}@ 1 \end{codeblock} \pnum -\indexlibrary{\idxhdr{cstdalign}}% -\indexlibrary{\idxhdr{stdalign.h}}% +\indexhdr{cstdalign}% +\indexhdr{stdalign.h}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}, with the following changes: The header \tcode{} and the header \tcode{} shall not @@ -91,14 +91,14 @@ \rSec2[depr.cstdbool.syn]{Header \tcode{} synopsis} -\indexlibrary{\idxhdr{cstdbool}}% +\indexhdr{cstdbool}% \indexlibrary{\idxcode{__bool_true_false_are_defined}}% \begin{codeblock} #define @\xname{bool_true_false_are_defined}@ 1 \end{codeblock} \pnum -\indexlibrary{\idxhdr{stdbool.h}}% +\indexhdr{stdbool.h}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}, with the following changes: The header \tcode{} and the header \tcode{} shall not @@ -108,7 +108,7 @@ \rSec2[depr.ctgmath.syn]{Header \tcode{} synopsis} -\indexlibrary{\idxhdr{ctgmath}}% +\indexhdr{ctgmath}% \begin{codeblock} #include #include @@ -129,7 +129,7 @@ \pnum For compatibility with the \indextext{library!C standard}% -C standard library, the \Cpp standard library provides +C standard library, the \Cpp{} standard library provides the \defnx{C headers}{headers!C library} shown in Table~\ref{tab:future.c.headers}. \begin{floattable}{C headers}{tab:future.c.headers} @@ -196,10 +196,8 @@ \pnum \begin{example} The header -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% -\indextext{\idxhdr{stdlib.h}}% -\indexlibrary{\idxhdr{stdlib.h}}% +\indexhdr{cstdlib}% +\indexhdr{stdlib.h}% \tcode{} assuredly provides its declarations and definitions within the namespace \tcode{std}. It may also provide these names within the @@ -212,12 +210,92 @@ the namespace \tcode{std}. \end{example} +\rSec1[depr.relops]{Relational operators} + +\pnum +The header \tcode{} +\indexhdr{utility}% +has the following additions: + +\begin{codeblock} +namespace std::rel_ops { + template bool operator!=(const T&, const T&); + template bool operator> (const T&, const T&); + template bool operator<=(const T&, const T&); + template bool operator>=(const T&, const T&); +} +\end{codeblock} + +\pnum +To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} +and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, +the library provides the following: + +\indexlibrary{\idxcode{operator"!=}}% +\begin{itemdecl} +template bool operator!=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). + +\pnum +\returns +\tcode{!(x == y)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>}}% +\begin{itemdecl} +template bool operator>(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{y < x}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}}% +\begin{itemdecl} +template bool operator<=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}}% +\begin{itemdecl} +template bool operator>=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{!(x < y)}. +\end{itemdescr} + \rSec1[depr.str.strstreams]{\tcode{char*} streams} \pnum The header -\indextext{\idxhdr{strstream}}% -\indexlibrary{\idxhdr{strstream}}% +\indexhdr{strstream}% \tcode{} defines three types that associate stream buffers with character array objects and assist reading and writing such objects. @@ -436,14 +514,12 @@ \indexlibrary{\idxcode{strlen}}% \tcode{strlen(const char*)} is declared in -\indextext{\idxhdr{cstring}}% -\indexlibrary{\idxhdr{cstring}}% +\indexhdr{cstring}% \tcode{}\iref{cstring.syn}. The macro \tcode{INT_MAX} is defined in -\indextext{\idxhdr{climits}}% -\indexlibrary{\idxhdr{climits}}% +\indexhdr{climits}% \tcode{}\iref{climits.syn}.} \end{itemize} @@ -911,7 +987,7 @@ \tcode{istream(\&sb)} and initializing \tcode{sb} with \tcode{strstreambuf(s,0)}. -\tcode{s} shall designate the first element of an \ntbs.% +\tcode{s} shall designate the first element of an \ntbs{}.% \indextext{NTBS} \end{itemdescr} @@ -1038,15 +1114,14 @@ If \tcode{(mode \& app) != 0}, then \tcode{s} shall designate the first element of an array of \tcode{n} elements that -contains an \ntbs whose first element is designated by \tcode{s}. +contains an \ntbs{} whose first element is designated by \tcode{s}. \indextext{NTBS}% The constructor is \tcode{strstreambuf(s, n, s + std::strlen(s))}.\footnote{The function signature \indexlibrary{\idxcode{strlen}}% \tcode{strlen(const char*)} is declared in -\indextext{\idxhdr{cstring}}% -\indexlibrary{\idxhdr{cstring}}% +\indexhdr{cstring}% \tcode{}\iref{cstring.syn}.} \end{itemize} \end{itemdescr} @@ -1106,7 +1181,7 @@ class strstream : public basic_iostream { public: - // Types + // types using char_type = char; using int_type = char_traits::int_type; using pos_type = char_traits::pos_type; @@ -1118,7 +1193,7 @@ ios_base::openmode mode = ios_base::in|ios_base::out); virtual ~strstream(); - // Members: + // members strstreambuf* rdbuf() const; void freeze(bool freezefl = true); int pcount() const; @@ -1187,7 +1262,7 @@ \tcode{(mode \& app) != 0}, then \tcode{s} shall designate the first element of an array of \tcode{n} elements that contains -an \ntbs whose first element is designated by \tcode{s}. +an \ntbs{} whose first element is designated by \tcode{s}. The constructor is \tcode{strstreambuf(s,n,s + std::strlen(s))}. \indexlibrary{\idxcode{strstream}!destructor}% @@ -1259,8 +1334,7 @@ \pnum The header -\indextext{\idxhdr{exception}}% -\indexlibrary{\idxhdr{exception}}% +\indexhdr{exception}% \tcode{} has the following addition: \indexlibrary{\idxcode{iterator}}% @@ -1392,7 +1466,7 @@ using second_argument_type = weak_ptr; }; - template class reference_wrapper { + template class reference_wrapper { public: using result_type = @\seebelow@; // not always defined using argument_type = @\seebelow@; // not always defined @@ -1400,113 +1474,113 @@ using second_argument_type = @\seebelow@; // not always defined }; - template struct plus { + template struct plus { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct minus { + template struct minus { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct multiplies { + template struct multiplies { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct divides { + template struct divides { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct modulus { + template struct modulus { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct negate { + template struct negate { using argument_type = T; using result_type = T; }; - template struct equal_to { + template struct equal_to { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct not_equal_to { + template struct not_equal_to { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct greater { + template struct greater { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct less { + template struct less { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct greater_equal { + template struct greater_equal { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct less_equal { + template struct less_equal { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct logical_and { + template struct logical_and { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct logical_or { + template struct logical_or { using first_argument_type = T; using second_argument_type = T; using result_type = bool; }; - template struct logical_not { + template struct logical_not { using argument_type = T; using result_type = bool; }; - template struct bit_and { + template struct bit_and { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct bit_or { + template struct bit_or { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct bit_xor { + template struct bit_xor { using first_argument_type = T; using second_argument_type = T; using result_type = T; }; - template struct bit_not { + template struct bit_not { using argument_type = T; using result_type = T; }; @@ -1627,7 +1701,7 @@ \indexlibrarymember{second_argument_type}{multimap::value_compare}% \begin{codeblock} namespace std { - template + template class map::value_compare { public: using result_type = bool; @@ -1635,7 +1709,7 @@ using second_argument_type = value_type; }; - template + template class multimap::value_compare { public: using result_type = bool; @@ -1649,8 +1723,7 @@ \pnum The header -\indextext{\idxhdr{functional}}% -\indexlibrary{\idxhdr{functional}}% +\indexhdr{functional}% \tcode{} has the following additions: \indexlibrary{\idxcode{unary_negate}}% @@ -1659,11 +1732,11 @@ \indexlibrary{\idxcode{not2}}% \begin{codeblock} namespace std { - template class unary_negate; - template + template class unary_negate; + template constexpr unary_negate not1(const Predicate&); - template class binary_negate; - template + template class binary_negate; + template constexpr binary_negate not2(const Predicate&); } \end{codeblock} @@ -1677,7 +1750,7 @@ \indexlibrarymember{argument_type}{unary_negate}% \indexlibrarymember{result_type}{unary_negate}% \begin{codeblock} -template +template class unary_negate { public: constexpr explicit unary_negate(const Predicate& pred); @@ -1698,7 +1771,7 @@ \indexlibrary{\idxcode{not1}}% \begin{itemdecl} -template +template constexpr unary_negate not1(const Predicate& pred); \end{itemdecl} @@ -1711,7 +1784,7 @@ \indexlibrarymember{second_argument_type}{binary_negate}% \indexlibrarymember{result_type}{binary_negate}% \begin{codeblock} -template +template class binary_negate { public: constexpr explicit binary_negate(const Predicate& pred); @@ -1736,7 +1809,7 @@ \indexlibrary{\idxcode{not2}}% \begin{itemdecl} -template +template constexpr binary_negate not2(const Predicate& pred); \end{itemdecl} @@ -1753,18 +1826,18 @@ \indexlibrary{\idxcode{allocator}}% \begin{codeblock} namespace std { - // specialize for \tcode{void}: - template <> class allocator { + // specialization for \tcode{void} + template<> class allocator { public: using value_type = void; using pointer = void*; using const_pointer = const void*; // reference-to-\tcode{void} members are impossible. - template struct rebind { using other = allocator; }; + template struct rebind { using other = allocator; }; }; - template class allocator { + template class allocator { public: using size_type = size_t; using difference_type = ptrdiff_t; @@ -1772,7 +1845,7 @@ using const_pointer = const T*; using reference = T&; using const_reference = const T&; - template struct rebind { using other = allocator; }; + template struct rebind { using other = allocator; }; T* address(T& x) const noexcept; const T* address(const T& x) const noexcept; @@ -1781,7 +1854,7 @@ template void construct(U* p, Args&&... args); - template + template void destroy(U* p); size_t max_size() const noexcept; @@ -1825,7 +1898,7 @@ \indexlibrarymember{construct}{allocator}% \begin{itemdecl} -template +template void construct(U* p, Args&&... args); \end{itemdecl} @@ -1837,7 +1910,7 @@ \indexlibrarymember{destroy}{allocator}% \begin{itemdecl} -template +template void destroy(U* p); \end{itemdecl} @@ -1863,14 +1936,13 @@ \pnum The header -\indextext{\idxhdr{memory}}% -\indexlibrary{\idxhdr{memory}}% +\indexhdr{memory}% \tcode{} has the following addition: \indexlibrary{\idxcode{raw_storage_iterator}}% \begin{codeblock} namespace std { - template + template class raw_storage_iterator { public: using iterator_category = output_iterator_tag; @@ -1998,22 +2070,21 @@ \pnum The header -\indextext{\idxhdr{memory}}% -\indexlibrary{\idxhdr{memory}}% +\indexhdr{memory}% \tcode{} has the following additions: \begin{codeblock} namespace std { - template + template pair get_temporary_buffer(ptrdiff_t n) noexcept; - template + template void return_temporary_buffer(T* p); } \end{codeblock} \indexlibrary{\idxcode{get_temporary_buffer}}% \begin{itemdecl} -template +template pair get_temporary_buffer(ptrdiff_t n) noexcept; \end{itemdecl} @@ -2047,7 +2118,7 @@ \indexlibrary{\idxcode{return_temporary_buffer}}% \begin{itemdecl} -template void return_temporary_buffer(T* p); +template void return_temporary_buffer(T* p); \end{itemdecl} \begin{itemdescr} @@ -2070,46 +2141,87 @@ \pnum The header -\indextext{\idxhdr{type_traits}}% -\indexlibrary{\idxhdr{type_traits}}% +\indexhdr{type_traits}% \tcode{} has the following addition: \indexlibrary{\idxcode{is_literal_type}}% \begin{codeblock} namespace std { - template struct is_literal_type; + template struct is_literal_type; + template constexpr bool is_literal_type_v = is_literal_type::value; - template constexpr bool is_literal_type_v = is_literal_type::value; + template struct result_of; // not defined + template struct result_of; + template using result_of_t = typename result_of::type; - template struct result_of; // not defined - template struct result_of; - - template using result_of_t = typename result_of::type; + template struct is_pod; + template inline constexpr bool is_pod_v = is_pod::value; } \end{codeblock} +\pnum +The behavior of a program that adds specializations for +any of the templates defined in this subclause is undefined, +unless explicitly permitted by the specification of the corresponding template. + +\begin{itemdecl} +template struct is_literal_type; +\end{itemdecl} + +\begin{itemdescr} \pnum \requires -For \tcode{is_literal_type}, \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\tcode{void}. -For \tcode{result_of}, -\tcode{Fn} and all types in the parameter pack \tcode{ArgTypes} shall be complete types, -\cv{}~\tcode{void}, or arrays of unknown bound. \pnum \tcode{is_literal_type} is a \tcode{UnaryTypeTrait}\iref{meta.rqmts} with a base characteristic of \tcode{true_type} if \tcode{T} is a literal type\iref{basic.types}, and \tcode{false_type} otherwise. +\end{itemdescr} + +\begin{itemdecl} +template struct result_of; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\tcode{Fn} and all types in the parameter pack \tcode{ArgTypes} shall be complete types, +\cv{}~\tcode{void}, or arrays of unknown bound. + +\pnum The partial specialization \tcode{result_of} is a -\tcode{TransformationTrait} whose member typedef \tcode{type} is defined -if and only if \tcode{invoke_result::type} is defined. +\tcode{TransformationTrait}\iref{meta.rqmts} whose member typedef \tcode{type} is defined +if and only if \tcode{invoke_result::type}\iref{func.invoke} is defined. If \tcode{type} is defined, it names the same type as \tcode{invoke_result_t}. +\end{itemdescr} + +\begin{itemdecl} +template struct is_pod; +\end{itemdecl} +\begin{itemdescr} \pnum -The behavior of a program that adds specializations for -any of the templates defined in this subclause is undefined, -unless explicitly permitted by the specification of the corresponding template. +\requires +\tcode{remove_all_extents_t} shall be a complete type or \cv{} \tcode{void}. + +\pnum +\tcode{is_pod} is a \tcode{UnaryTypeTrait}\iref{meta.rqmts} +with a base characteristic of \tcode{true_type} +if \tcode{T} is a POD type, +and \tcode{false_type} otherwise. +\indextext{POD}% +A POD class is a class that is both a trivial class and a standard-layout class, +and has no non-static data members of type non-POD class (or array thereof). +A POD type is a scalar type, a POD class, an array of such a type, +or a cv-qualified version of one of these types. + +\pnum +\begin{note} +It is unspecified whether a closure type\iref{expr.prim.lambda.closure} is a POD type. +\end{note} +\end{itemdescr} \rSec1[depr.iterator.primitives]{Deprecated iterator primitives} @@ -2117,15 +2229,14 @@ \pnum The header -\indextext{\idxhdr{iterator}}% -\indexlibrary{\idxhdr{iterator}}% +\indexhdr{iterator}% \tcode{} has the following addition: \indexlibrary{\idxcode{iterator}}% \begin{codeblock} namespace std { template + class Pointer = T*, class Reference = T&> struct iterator { using iterator_category = Category; using value_type = T; @@ -2149,7 +2260,7 @@ \pnum \begin{example} -If a \Cpp program wants to define a bidirectional iterator for some data +If a \Cpp{} program wants to define a bidirectional iterator for some data structure containing \tcode{double} and such that it works on a large memory model of the implementation, it can do so with: @@ -2186,11 +2297,252 @@ \pnum\returns \tcode{use_count() == 1}. \end{itemdescr} +\rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access} + +\pnum +The header \tcode{} has the following additions: + +\indexlibrary{\idxcode{shared_ptr}}% +\begin{codeblock} +namespace std { + template + bool atomic_is_lock_free(const shared_ptr* p); + + template + shared_ptr atomic_load(const shared_ptr* p); + template + shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); + + template + void atomic_store(shared_ptr* p, shared_ptr r); + template + void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); + + template + shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); + template + shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); + + template + bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); + template + bool atomic_compare_exchange_strong(shared_ptr* p, shared_ptr* v, shared_ptr w); + template + bool atomic_compare_exchange_weak_explicit( + shared_ptr* p, shared_ptr* v, shared_ptr w, + memory_order success, memory_order failure); + template + bool atomic_compare_exchange_strong_explicit( + shared_ptr* p, shared_ptr* v, shared_ptr w, + memory_order success, memory_order failure); +} +\end{codeblock} + +\pnum +Concurrent access to a \tcode{shared_ptr} object from multiple threads does not +introduce a data race if the access is done exclusively via the functions in +this subclause and the instance is passed as their first argument. + +\pnum +The meaning of the arguments of type \tcode{memory_order} is explained in~\ref{atomics.order}. + +\indexlibrarymember{atomic_is_lock_free}{shared_ptr}% +\begin{itemdecl} +template bool atomic_is_lock_free(const shared_ptr* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\returns \tcode{true} if atomic access to \tcode{*p} is lock-free, \tcode{false} otherwise. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_load}{shared_ptr}% +\begin{itemdecl} +template shared_ptr atomic_load(const shared_ptr* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\returns \tcode{atomic_load_explicit(p, memory_order_seq_cst)}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_load_explicit}{shared_ptr}% +\begin{itemdecl} +template shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\requires \tcode{mo} shall not be \tcode{memory_order_release} or \tcode{memory_order_acq_rel}. + +\pnum +\returns \tcode{*p}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_store}{shared_ptr}% +\begin{itemdecl} +template void atomic_store(shared_ptr* p, shared_ptr r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\effects As if by \tcode{atomic_store_explicit(p, r, memory_order_seq_cst)}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_store_explicit}{shared_ptr}% +\begin{itemdecl} +template void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\requires \tcode{mo} shall not be \tcode{memory_order_acquire} or \tcode{memory_order_acq_rel}. + +\pnum +\effects As if by \tcode{p->swap(r)}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_exchange}{shared_ptr}% +\begin{itemdecl} +template shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\returns \tcode{atomic_exchange_explicit(p, r, memory_order_seq_cst)}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_exchange_explicit}{shared_ptr}% +\begin{itemdecl} +template + shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null. + +\pnum +\effects As if by \tcode{p->swap(r)}. + +\pnum +\returns The previous value of \tcode{*p}. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_compare_exchange_weak}{shared_ptr}% +\begin{itemdecl} +template + bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null and \tcode{v} shall not be null. + +\pnum +\returns +\begin{codeblock} +atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst) +\end{codeblock} + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{atomic_compare_exchange_strong}{shared_ptr}% +\begin{itemdecl} +template + bool atomic_compare_exchange_strong(shared_ptr* p, shared_ptr* v, shared_ptr w); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +atomic_compare_exchange_strong_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst) +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{atomic_compare_exchange_weak_explicit}{shared_ptr}% +\indexlibrarymember{atomic_compare_exchange_strong_explicit}{shared_ptr}% +\begin{itemdecl} +template + bool atomic_compare_exchange_weak_explicit( + shared_ptr* p, shared_ptr* v, shared_ptr w, + memory_order success, memory_order failure); +template + bool atomic_compare_exchange_strong_explicit( + shared_ptr* p, shared_ptr* v, shared_ptr w, + memory_order success, memory_order failure); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{p} shall not be null and \tcode{v} shall not be null. +The \tcode{failure} argument shall not be \tcode{memory_order_release} nor +\tcode{memory_order_acq_rel}. + +\pnum +\effects If \tcode{*p} is equivalent to \tcode{*v}, assigns \tcode{w} to +\tcode{*p} and has synchronization semantics corresponding to the value of +\tcode{success}, otherwise assigns \tcode{*p} to \tcode{*v} and has +synchronization semantics corresponding to the value of \tcode{failure}. + +\pnum +\returns \tcode{true} if \tcode{*p} was equivalent to \tcode{*v}, \tcode{false} otherwise. + +\pnum +\throws Nothing. + +\pnum +\remarks Two \tcode{shared_ptr} objects are equivalent if they store the same +pointer value and share ownership. +The weak form may fail spuriously. See~\ref{atomics.types.operations}. +\end{itemdescr} + \rSec1[depr.locale.stdcvt]{Deprecated standard code conversion facets} \pnum -\indextext{\idxhdr{codecvt}}% -\indexlibrary{\idxhdr{codecvt}}% +\indexhdr{codecvt}% The header \tcode{} provides code conversion facets for various character encodings. \rSec2[depr.codecvt.syn]{Header \tcode{} synopsis} @@ -2207,21 +2559,21 @@ little_endian = 1 }; - template + template class codecvt_utf8 : public codecvt { public: explicit codecvt_utf8(size_t refs = 0); ~codecvt_utf8(); }; - template + template class codecvt_utf16 : public codecvt { public: explicit codecvt_utf16(size_t refs = 0); ~codecvt_utf16(); }; - template + template class codecvt_utf8_utf16 : public codecvt { public: explicit codecvt_utf8_utf16(size_t refs = 0); @@ -2305,13 +2657,13 @@ \begin{codeblock} namespace std { - template , - class Byte_alloc = allocator> + template, + class Byte_alloc = allocator> class wstring_convert; - template > + template> class wbuffer_convert; } \end{codeblock} @@ -2336,9 +2688,9 @@ \indexlibrary{\idxcode{wstring_convert}}% \begin{codeblock} namespace std { - template , - class Byte_alloc = allocator> + template, + class Byte_alloc = allocator> class wstring_convert { public: using byte_string = basic_string, Byte_alloc>; @@ -2589,7 +2941,7 @@ \indexlibrary{\idxcode{wbuffer_convert}}% \begin{codeblock} namespace std { - template > + template> class wbuffer_convert : public basic_streambuf { public: using state_type = typename Codecvt::state_type; diff --git a/source/grammar.tex b/source/grammar.tex index 96e779c393..02135b574f 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -3,10 +3,10 @@ \pnum \indextext{grammar}% \indextext{summary!syntax}% -This summary of \Cpp grammar is intended to be an aid to comprehension. +This summary of \Cpp{} grammar is intended to be an aid to comprehension. It is not an exact statement of the language. In particular, the grammar described here accepts -a superset of valid \Cpp constructs. +a superset of valid \Cpp{} constructs. Disambiguation rules~(\ref{stmt.ambig}, \ref{dcl.spec}, \ref{class.member.lookup}) must be applied to distinguish expressions from declarations. Further, access control, ambiguity, and type rules must be used diff --git a/source/intro.tex b/source/intro.tex index 977344538f..0a06541b6f 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -5,17 +5,17 @@ \pnum \indextext{scope|(}% This document specifies requirements for implementations -of the \Cpp programming language. The first such requirement is that +of the \Cpp{} programming language. The first such requirement is that they implement the language, so this document also -defines \Cpp. Other requirements and relaxations of the first +defines \Cpp{}. Other requirements and relaxations of the first requirement appear at various places within this document. \pnum -\Cpp is a general purpose programming language based on the C +\Cpp{} is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:2011 \doccite{Programming languages --- C} (hereinafter referred to as the \defnx{C standard}{C!standard}). In addition to -the facilities provided by C, \Cpp provides additional data types, +the facilities provided by C, \Cpp{} provides additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities.% @@ -56,7 +56,7 @@ \defnx{C standard library}{C!standard library}.% \footnote{With the qualifications noted in \ref{\firstlibchapter} through \ref{\lastlibchapter} and in \ref{diff.library}, the C standard -library is a subset of the \Cpp standard library.} +library is a subset of the \Cpp{} standard library.} \pnum The operating system interface described in ISO/IEC 9945:2003 is @@ -219,7 +219,7 @@ parameter type list\iref{dcl.fct}, enclosing namespace (if any), and -\grammarterm{requires-clause}\iref{temp.constr.decl} (if any) +trailing \grammarterm{requires-clause}\iref{dcl.decl} (if any) \begin{defnote} Signatures are used as a basis for @@ -235,7 +235,7 @@ return type, \grammarterm{template-head}, and -\grammarterm{requires-clause}\iref{temp.constr.decl} (if any) +trailing \grammarterm{requires-clause}\iref{dcl.decl} (if any) \indexdefn{signature}% \definition{signature}{defns.signature.spec} @@ -251,7 +251,7 @@ \cv-qualifiers (if any), \grammarterm{ref-qualifier} (if any), and -\grammarterm{requires-clause}\iref{temp.constr.decl} (if any) +trailing \grammarterm{requires-clause}\iref{dcl.decl} (if any) \indexdefn{signature}% \definition{signature}{defns.signature.member.templ} @@ -264,7 +264,7 @@ return type (if any), \grammarterm{template-head}, and -\grammarterm{requires-clause}\iref{temp.constr.decl} (if any) +trailing \grammarterm{requires-clause}\iref{dcl.decl} (if any) \indexdefn{signature}% \definition{signature}{defns.signature.member.spec} @@ -319,7 +319,7 @@ \indexdefn{program!well-formed}% \definition{well-formed program}{defns.well.formed} -\Cpp program constructed according to the syntax rules, diagnosable +\Cpp{} program constructed according to the syntax rules, diagnosable semantic rules, and the one-definition rule\iref{basic.def.odr}% \indextext{definitions|)} @@ -361,7 +361,7 @@ \pnum \indextext{conformance requirements!method of description}% -Although this document states only requirements on \Cpp +Although this document states only requirements on \Cpp{} implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning: @@ -407,7 +407,7 @@ \pnum The names defined in the library have namespace -scope\iref{basic.namespace}. A \Cpp translation +scope\iref{basic.namespace}. A \Cpp{} translation unit\iref{lex.phases} obtains access to these names by including the appropriate standard library header\iref{cpp.include}. @@ -415,7 +415,7 @@ The templates, classes, functions, and objects in the library have external linkage\iref{basic.link}. The implementation provides definitions for standard library entities, as necessary, while combining -translation units to form a complete \Cpp program\iref{lex.phases}.% +translation units to form a complete \Cpp{} program\iref{lex.phases}.% \indextext{conformance requirements!library|)} \pnum @@ -443,336 +443,7 @@ \indextext{conformance requirements!general|)}% \indextext{conformance requirements|)}% -\rSec1[intro.structure]{Structure of this document} - -\pnum -\indextext{standard!structure of|(}% -\indextext{standard!structure of}% -\ref{lex} through \ref{cpp} describe the \Cpp programming -language. That description includes detailed syntactic specifications in -a form described in~\ref{syntax}. For convenience, \ref{gram} -repeats all such syntactic specifications. - -\pnum -\ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} -(the \defn{library clauses}) describe the \Cpp standard library. -That description includes detailed descriptions of the -entities and macros -that constitute the library, in a form described in \ref{library}. - -\pnum -\ref{implimits} recommends lower bounds on the capacity of conforming -implementations. - -\pnum -\ref{diff} summarizes the evolution of \Cpp since its first -published description, and explains in detail the differences between -\Cpp and C\@. Certain features of \Cpp exist solely for compatibility -purposes; \ref{depr} describes those features. - -\pnum -Throughout this document, each example is introduced by -``\noteintro{Example}'' and terminated by ``\noteoutro{example}''. Each note is -introduced by ``\noteintro{Note}'' and terminated by ``\noteoutro{note}''. Examples -and notes may be nested.% -\indextext{standard!structure of|)} - -\rSec1[syntax]{Syntax notation} - -\pnum -\indextext{notation!syntax|(}% -In the syntax notation used in this document, syntactic -categories are indicated by \grammarterm{italic} type, and literal words -and characters in \tcode{constant} \tcode{width} type. Alternatives are -listed on separate lines except in a few cases where a long set of -alternatives is marked by the phrase ``one of''. If the text of an alternative is too long to fit on a line, the text is continued on subsequent lines indented from the first one. -An optional terminal or non-terminal symbol is indicated by the subscript -``\opt'', so - -\begin{ncbnf} -\terminal{\{} expression\opt{} \terminal{\}} -\end{ncbnf} - -indicates an optional expression enclosed in braces.% - -\pnum -Names for syntactic categories have generally been chosen according to -the following rules: -\begin{itemize} -\item \grammarterm{X-name} is a use of an identifier in a context that -determines its meaning (e.g., \grammarterm{class-name}, -\grammarterm{typedef-name}). -\item \grammarterm{X-id} is an identifier with no context-dependent meaning -(e.g., \grammarterm{qualified-id}). -\item \grammarterm{X-seq} is one or more \grammarterm{X}'s without intervening -delimiters (e.g., \grammarterm{declaration-seq} is a sequence of -declarations). -\item \grammarterm{X-list} is one or more \grammarterm{X}'s separated by -intervening commas (e.g., \grammarterm{identifier-list} is a sequence of -identifiers separated by commas). -\end{itemize}% -\indextext{notation!syntax|)} - -\rSec1[intro.memory]{The \Cpp memory model} - -\pnum -\indextext{memory model|(}% -The fundamental storage unit in the \Cpp memory model is the -\defn{byte}. -A byte is at least large enough to contain any member of the basic -\indextext{character set!basic execution}% -execution character set\iref{lex.charset} -and the eight-bit code units of the Unicode UTF-8 encoding form -and is composed of a contiguous sequence of -bits,\footnote{The number of bits in a byte is reported by the macro -\tcode{CHAR_BIT} in the header \tcode{}.} -the number of which is \impldef{bits in a byte}. The least -significant bit is called the \defn{low-order bit}; the most -significant bit is called the \defn{high-order bit}. The memory -available to a \Cpp program consists of one or more sequences of -contiguous bytes. Every byte has a unique address. - -\pnum -\begin{note} The representation of types is described -in~\ref{basic.types}. \end{note} - -\pnum -A \defn{memory location} is either an object of scalar type or a maximal -sequence of adjacent bit-fields all having nonzero width. \begin{note} Various -features of the language, such as references and virtual functions, might -involve additional memory locations that are not accessible to programs but are -managed by the implementation. \end{note} Two or more threads of -execution\iref{intro.multithread} can access separate memory -locations without interfering with each other. - -\pnum -\begin{note} Thus a bit-field and an adjacent non-bit-field are in separate memory -locations, and therefore can be concurrently updated by two threads of execution -without interference. The same applies to two bit-fields, if one is declared -inside a nested struct declaration and the other is not, or if the two are -separated by a zero-length bit-field declaration, or if they are separated by a -non-bit-field declaration. It is not safe to concurrently update two bit-fields -in the same struct if all fields between them are also bit-fields of nonzero -width. \end{note} - -\pnum -\begin{example} A structure declared as - -\begin{codeblock} -struct { - char a; - int b:5, - c:11, - :0, - d:8; - struct {int ee:8;} e; -} -\end{codeblock} - -contains four separate memory locations: The member \tcode{a} and bit-fields -\tcode{d} and \tcode{e.ee} are each separate memory locations, and can be -modified concurrently without interfering with each other. The bit-fields -\tcode{b} and \tcode{c} together constitute the fourth memory location. The -bit-fields \tcode{b} and \tcode{c} cannot be concurrently modified, but -\tcode{b} and \tcode{a}, for example, can be. \end{example}% -\indextext{memory model|)} - -\rSec1[intro.object]{The \Cpp object model} - -\pnum -\indextext{object model|(}% -The constructs in a \Cpp program create, destroy, refer to, access, and -manipulate objects. -An \defn{object} is created -by a definition\iref{basic.def}, -by a \grammarterm{new-expression}\iref{expr.new}, -when implicitly changing the active member of a union\iref{class.union}, -or -when a temporary object is created~(\ref{conv.rval}, \ref{class.temporary}). -An object occupies a region of storage -in its period of construction\iref{class.cdtor}, -throughout its lifetime\iref{basic.life}, -and -in its period of destruction\iref{class.cdtor}. -\begin{note} A function is not an object, regardless of whether or not it -occupies storage in the way that objects do. \end{note} -The properties of an -object are determined when the object is created. An object can have a -name\iref{basic}. An object has a storage -duration\iref{basic.stc} which influences its -lifetime\iref{basic.life}. An object has a -type\iref{basic.types}. -Some objects are -polymorphic\iref{class.virtual}; the implementation -generates information associated with each such object that makes it -possible to determine that object's type during program execution. For -other objects, the interpretation of the values found therein is -determined by the type of the \grammarterm{expression}{s}\iref{expr} -used to access them. - -\pnum -\indextext{subobject}% -Objects can contain other objects, called \defnx{subobjects}{subobject}. -A subobject can be -a \defn{member subobject}\iref{class.mem}, a \defn{base class subobject}\iref{class.derived}, -or an array element. -\indextext{object!complete}% -An object that is not a subobject of any other object is called a \defn{complete -object}. -If an object is created -in storage associated with a member subobject or array element \placeholder{e} -(which may or may not be within its lifetime), -the created object -is a subobject of \placeholder{e}'s containing object if: -\begin{itemize} -\item -the lifetime of \placeholder{e}'s containing object has begun and not ended, and -\item -the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and -\item -the new object is of the same type as \placeholder{e} (ignoring cv-qualification). -\end{itemize} -\begin{note} -If the subobject contains a reference member or a \tcode{const} subobject, -the name of the original subobject cannot be used to access the new object\iref{basic.life}. -\end{note} -\begin{example} -\begin{codeblock} -struct X { const int n; }; -union U { X x; float f; }; -void tong() { - U u = {{ 1 }}; - u.f = 5.f; // OK, creates new subobject of \tcode{u}\iref{class.union} - X *p = new (&u.x) X {2}; // OK, creates new subobject of \tcode{u} - assert(p->n == 2); // OK - assert(*std::launder(&u.x.n) == 2); // OK - assert(u.x.n == 2); // undefined behavior, \tcode{u.x} does not name new subobject -} -\end{codeblock} -\end{example} - -\pnum -\indextext{object!providing storage for}% -If a complete object is created\iref{expr.new} -in storage associated with another object \placeholder{e} -of type ``array of $N$ \tcode{unsigned char}'' or -of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, -that array \defn{provides storage} -for the created object if: -\begin{itemize} -\item -the lifetime of \placeholder{e} has begun and not ended, and -\item -the storage for the new object fits entirely within \placeholder{e}, and -\item -there is no smaller array object that satisfies these constraints. -\end{itemize} -\begin{note} -If that portion of the array -previously provided storage for another object, -the lifetime of that object ends -because its storage was reused\iref{basic.life}. -\end{note} -\begin{example} -\begin{codeblock} -template -struct AlignedUnion { - alignas(T...) unsigned char data[max(sizeof(T)...)]; -}; -int f() { - AlignedUnion au; - int *p = new (au.data) int; // OK, \tcode{au.data} provides storage - char *c = new (au.data) char(); // OK, ends lifetime of \tcode{*p} - char *d = new (au.data + 1) char(); - return *c + *d; // OK -} - -struct A { unsigned char a[32]; }; -struct B { unsigned char b[16]; }; -A a; -B *b = new (a.a + 8) B; // \tcode{a.a} provides storage for \tcode{*b} -int *p = new (b->b + 4) int; // \tcode{b->b} provides storage for \tcode{*p} - // \tcode{a.a} does not provide storage for \tcode{*p} (directly), - // but \tcode{*p} is nested within \tcode{a} (see below) -\end{codeblock} -\end{example} - -\pnum -\indextext{object!nested within}% -An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if: -\begin{itemize} -\item -\placeholder{a} is a subobject of \placeholder{b}, or -\item -\placeholder{b} provides storage for \placeholder{a}, or -\item -there exists an object \placeholder{c} -where \placeholder{a} is nested within \placeholder{c}, -and \placeholder{c} is nested within \placeholder{b}. -\end{itemize} - -\pnum -For every object \tcode{x}, there is some object called the -\defn{complete object of} \tcode{x}, determined as follows: -\begin{itemize} -\item -If \tcode{x} is a complete object, then the complete object -of \tcode{x} is itself. - -\item -Otherwise, the complete object of \tcode{x} is the complete object -of the (unique) object that contains \tcode{x}. -\end{itemize} - -\pnum -If a complete object, a data member\iref{class.mem}, or an array element is of -class type, its type is considered the \defn{most derived -class}, to distinguish it from the class type of any base class subobject; -an object of a most derived class type or of a non-class type is called a -\defn{most derived object}. - -\pnum -\indextext{most derived object!bit-field}% -Unless it is a bit-field\iref{class.bit}, a most derived object shall have a -nonzero size and shall occupy one or more bytes of storage. Base class -subobjects may have zero size. An object of trivially copyable or -standard-layout type\iref{basic.types} shall occupy contiguous bytes of -storage. - -\pnum -\indextext{most derived object!bit-field}% -\indextext{most derived object!zero size subobject}% -Unless an object is a bit-field or a base class subobject of zero size, the -address of that object is the address of the first byte it occupies. -Two objects \placeholder{a} and \placeholder{b} -with overlapping lifetimes -that are not bit-fields -may have the same address -if one is nested within the other, -or -if at least one is a base class subobject of zero size -and they are of different types; -otherwise, they have distinct addresses.\footnote{Under the ``as-if'' rule an -implementation is allowed to store two objects at the same machine address or -not store an object at all if the program cannot observe the -difference\iref{intro.execution}.} - -\begin{example} -\begin{codeblock} -static const char test1 = 'x'; -static const char test2 = 'x'; -const bool b = &test1 != &test2; // always \tcode{true} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -\Cpp provides a variety of fundamental types and several ways of composing -new types from existing types\iref{basic.types}. -\end{note}% -\indextext{object model|)} - -\rSec1[intro.execution]{Program execution} +\rSec2[intro.abstract]{Abstract machine} \pnum \indextext{program execution|(}% @@ -823,7 +494,7 @@ \pnum Certain other operations are described in this document as undefined (for example, the effect of -attempting to modify a \tcode{const} object). +attempting to modify a const object). \begin{note} This document imposes no requirements on the behavior of programs that contain undefined behavior. \end{note} @@ -840,13 +511,6 @@ (not even with regard to operations preceding the first undefined operation). -\pnum -An instance of each object with automatic storage -duration\iref{basic.stc.auto} is associated with each entry into its -block. Such an object exists and retains its last-stored value during -the execution of the block and while the block is suspended (by a call -of a function or receipt of a signal). - \indextext{conformance requirements} \pnum The least requirements on a conforming implementation are: @@ -914,833 +578,82 @@ rewritten by the implementation in any of the above ways because the same result will occur. \end{note} -\pnum -A \defn{constituent expression} is defined as follows: -\begin{itemize} -\item -The constituent expression of an expression is that expression. -\item -The constituent expressions of a \grammarterm{braced-init-list} or -of a (possibly parenthesized) \grammarterm{expression-list} -are the constituent expressions of the elements of the respective list. -\item -The constituent expressions of a \grammarterm{brace-or-equal-initializer} -of the form \tcode{=}~\grammarterm{initializer-clause} -are the constituent expressions of the \grammarterm{initializer-clause}. -\end{itemize} -\begin{example} -\begin{codeblock} -struct A { int x; }; -struct B { int y; struct A a; }; -B b = { 5, { 1+1 } }; -\end{codeblock} -The constituent expressions of the \grammarterm{initializer} -used for the initialization of \tcode{b} are \tcode{5} and \tcode{1+1}. -\end{example} - -\pnum -The \defnx{immediate subexpressions}{immediate subexpression} of an expression \tcode{e} are -\begin{itemize} -\item -the constituent expressions of \tcode{e}'s operands\iref{expr}, -\item -any function call that \tcode{e} implicitly invokes, -\item -if \tcode{e} is a \grammarterm{lambda-expression}\iref{expr.prim.lambda}, -the initialization of the entities captured by copy and -the constituent expressions of the \grammarterm{initializer} of the \grammarterm{init-capture}{s}, -\item -if \tcode{e} is a function call\iref{expr.call} or implicitly invokes a function, -the constituent expressions of each default argument\iref{dcl.fct.default} -used in the call, or -\item -if \tcode{e} creates an aggregate object\iref{dcl.init.aggr}, -the constituent expressions of each default member initializer\iref{class.mem} -used in the initialization. -\end{itemize} - -\pnum -A \defn{subexpression} of an expression \tcode{e} is -an immediate subexpression of \tcode{e} or -a subexpression of an immediate subexpression of \tcode{e}. -\begin{note} -Expressions appearing in the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} -are not subexpressions of the \grammarterm{lambda-expression}. -\end{note} - -\pnum -A \defn{full-expression} is -\begin{itemize} -\item -an unevaluated operand\iref{expr}, -\item -a \grammarterm{constant-expression}\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, -\item -an invocation of a destructor generated at the end of the lifetime -of an object other than a temporary object\iref{class.temporary}, or -\item -an expression that is not a subexpression of another expression and -that is not otherwise part of a full-expression. -\end{itemize} -If a language construct is defined to produce an implicit call of a function, -a use of the language construct is considered to be an expression -for the purposes of this definition. -Conversions applied to the result of an expression in order to satisfy the requirements -of the language construct in which the expression appears -are also considered to be part of the full-expression. -For an initializer, performing the initialization of the entity -(including evaluating default member initializers of an aggregate) -is also considered part of the full-expression. -\begin{example} -\begin{codeblock} -struct S { - S(int i): I(i) { } // full-expression is initialization of \tcode{I} - int& v() { return I; } - ~S() noexcept(false) { } -private: - int I; -}; - -S s1(1); // full-expression is call of \tcode{S::S(int)} -void f() { - S s2 = 2; // full-expression is call of \tcode{S::S(int)} - if (S(3).v()) // full-expression includes lvalue-to-rvalue and - // \tcode{int} to \tcode{bool} conversions, performed before - // temporary is deleted at end of full-expression - { } - bool b = noexcept(S()); // exception specification of destructor of \tcode{S} - // considered for \tcode{noexcept} - // full-expression is destruction of \tcode{s2} at end of block -} -struct B { - B(S = S(0)); -}; -B b[2] = { B(), B() }; // full-expression is the entire initialization - // including the destruction of temporaries -\end{codeblock} -\end{example} - -\pnum -\begin{note} The evaluation of a full-expression can include the -evaluation of subexpressions that are not lexically part of the -full-expression. For example, subexpressions involved in evaluating -default arguments\iref{dcl.fct.default} are considered to -be created in the expression that calls the function, not the expression -that defines the default argument. \end{note} - -\pnum -\indextext{value computation|(}% -Reading an object designated by a \tcode{volatile} -glvalue\iref{basic.lval}, modifying an object, calling a library I/O -function, or calling a function that does any of those operations are -all -\defn{side effects}, which are changes in the state of the execution -environment. \defnx{Evaluation}{evaluation} of an expression (or a -subexpression) in general includes both value computations (including -determining the identity of an object for glvalue evaluation and fetching -a value previously assigned to an object for prvalue evaluation) and -initiation of side effects. When a call to a library I/O function -returns or an access through a volatile glvalue is evaluated the side -effect is considered complete, even though some external actions implied -by the call (such as the I/O itself) or by the \tcode{volatile} access -may not have completed yet. - -\pnum -\defnx{Sequenced before}{sequenced before} is an asymmetric, transitive, pair-wise relation between -evaluations executed by a single thread\iref{intro.multithread}, which induces -a partial order among those evaluations. Given any two evaluations \placeholder{A} and -\placeholder{B}, if \placeholder{A} is sequenced before \placeholder{B} -(or, equivalently, \placeholder{B} is \defn{sequenced after} \placeholder{A}), -then the execution of -\placeholder{A} shall precede the execution of \placeholder{B}. If \placeholder{A} is not sequenced -before \placeholder{B} and \placeholder{B} is not sequenced before \placeholder{A}, then \placeholder{A} and -\placeholder{B} are \defn{unsequenced}. \begin{note} The execution of unsequenced -evaluations can overlap. \end{note} Evaluations \placeholder{A} and \placeholder{B} are -\defn{indeterminately sequenced} when either \placeholder{A} is sequenced before -\placeholder{B} or \placeholder{B} is sequenced before \placeholder{A}, but it is unspecified which. -\begin{note} Indeterminately sequenced evaluations cannot overlap, but either -could be executed first. \end{note} -An expression \placeholder{X} -is said to be sequenced before -an expression \placeholder{Y} if -every value computation and every side effect -associated with the expression \placeholder{X} -is sequenced before -every value computation and every side effect -associated with the expression \placeholder{Y}. - -\pnum -Every -\indextext{value computation}% -value computation and -\indextext{side effects}% -side effect associated with a full-expression is -sequenced before every value computation and side effect associated with the -next full-expression to be evaluated.\footnote{As specified -in~\ref{class.temporary}, after a full-expression is evaluated, a sequence of -zero or more invocations of destructor functions for temporary objects takes -place, usually in reverse order of the construction of each temporary object.} - -\pnum -\indextext{evaluation!unspecified order of}% -Except where noted, evaluations of operands of individual operators and -of subexpressions of individual expressions are unsequenced. \begin{note} -In an expression that is evaluated more than once during the execution -of a program, unsequenced and indeterminately sequenced evaluations of -its subexpressions need not be performed consistently in different -evaluations. \end{note} The value computations of the operands of an -operator are sequenced before the value computation of the result of the -operator. If a -\indextext{side effects}% -side effect on a memory location\iref{intro.memory} is unsequenced -relative to either another side effect on the same memory location or -a value computation using the value of any object in the same memory location, -and they are not potentially concurrent\iref{intro.multithread}, -the behavior is undefined. -\begin{note} -The next section imposes similar, but more complex restrictions on -potentially concurrent computations. -\end{note} - -\begin{example} - -\begin{codeblock} -void g(int i) { - i = 7, i++, i++; // \tcode{i} becomes \tcode{9} - - i = i++ + 1; // the value of \tcode{i} is incremented - i = i++ + i; // the behavior is undefined - i = i + 1; // the value of \tcode{i} is incremented -} -\end{codeblock} -\end{example} - -\pnum -When calling a function (whether or not the function is inline), every -\indextext{value computation}% -value computation and -\indextext{side effects}% -side effect associated with any argument -expression, or with the postfix expression designating the called -function, is sequenced before execution of every expression or statement -in the body of the called function. -For each function invocation \placeholder{F}, -for every evaluation \placeholder{A} that occurs within \placeholder{F} and -every evaluation \placeholder{B} that does not occur within \placeholder{F} but -is evaluated on the same thread and as part of the same signal handler (if any), -either \placeholder{A} is sequenced before \placeholder{B} or -\placeholder{B} is sequenced before \placeholder{A}.\footnote{In other words, -function executions do not interleave with each other.} -\begin{note} -If \placeholder{A} and \placeholder{B} would not otherwise be sequenced then they are -indeterminately sequenced. -\end{note} -Several contexts in \Cpp cause evaluation of a function call, even -though no corresponding function call syntax appears in the translation -unit. -\begin{example} -Evaluation of a \grammarterm{new-expression} invokes one or more allocation -and constructor functions; see~\ref{expr.new}. For another example, -invocation of a conversion function\iref{class.conv.fct} can arise in -contexts in which no function call syntax appears. -\end{example} -The sequencing constraints on the execution of the called function (as -described above) are features of the function calls as evaluated, -whatever the syntax of the expression that calls the function might be.% -\indextext{value computation|)}% - -\indextext{behavior!on receipt of signal}% -\indextext{signal}% -\pnum -If a signal handler is executed as a result of a call to the \tcode{std::raise} -function, then the execution of the handler is sequenced after the invocation -of the \tcode{std::raise} function and before its return. -\begin{note} When a signal is received for another reason, the execution of the -signal handler is usually unsequenced with respect to the rest of the program. -\end{note} -\indextext{program execution|)} - -\rSec1[intro.multithread]{Multi-threaded executions and data races} - -\pnum -\indextext{threads!multiple|(}% -\indextext{operation!atomic|(}% -A \defn{thread of execution} (also known as a \defn{thread}) is a single flow of -control within a program, including the initial invocation of a specific -top-level function, and recursively including every function invocation -subsequently executed by the thread. \begin{note} When one thread creates another, -the initial call to the top-level function of the new thread is executed by the -new thread, not by the creating thread. \end{note} Every thread in a program can -potentially access every object and function in a program.\footnote{An object -with automatic or thread storage duration\iref{basic.stc} is associated with -one specific thread, and can be accessed by a different thread only indirectly -through a pointer or reference\iref{basic.compound}.} Under a hosted -implementation, a \Cpp program can have more than one thread running -concurrently. The execution of each thread proceeds as defined by the remainder -of this document. The execution of the entire program consists of an execution -of all of its threads. \begin{note} Usually the execution can be viewed as an -interleaving of all its threads. However, some kinds of atomic operations, for -example, allow executions inconsistent with a simple interleaving, as described -below. \end{note} Under a freestanding implementation, it is \impldef{number of -threads in a program under a freestanding implementation} whether a program can -have more than one thread of execution. - -\pnum -For a signal handler that is not executed as a result of a call to the -\tcode{std::raise} function, it is unspecified which thread of execution -contains the signal handler invocation. - -\rSec2[intro.races]{Data races} - -\pnum -The value of an object visible to a thread \placeholder{T} at a particular point is the -initial value of the object, a value assigned to the object by \placeholder{T}, or a -value assigned to the object by another thread, according to the rules below. -\begin{note} In some cases, there may instead be undefined behavior. Much of this -section is motivated by the desire to support atomic operations with explicit -and detailed visibility constraints. However, it also implicitly supports a -simpler view for more restricted programs. \end{note} - -\pnum -Two expression evaluations \defn{conflict} if one of them modifies a memory -location\iref{intro.memory} and the other one reads or modifies the same -memory location. - -\pnum -The library defines a number of atomic operations\iref{atomics} and -operations on mutexes\iref{thread} that are specially identified as -synchronization operations. These operations play a special role in making -assignments in one thread visible to another. A synchronization operation on one -or more memory locations is either a consume operation, an acquire operation, a -release operation, or both an acquire and release operation. A synchronization -operation without an associated memory location is a fence and can be either an -acquire fence, a release fence, or both an acquire and release fence. In -addition, there are relaxed atomic operations, which are not synchronization -operations, and atomic read-modify-write operations, which have special -characteristics. \begin{note} For example, a call that acquires a mutex will -perform an acquire operation on the locations comprising the mutex. -Correspondingly, a call that releases the same mutex will perform a release -operation on those same locations. Informally, performing a release operation on -\placeholder{A} forces prior -\indextext{side effects}% -side effects on other memory locations to become visible -to other threads that later perform a consume or an acquire operation on -\placeholder{A}. ``Relaxed'' atomic operations are not synchronization operations even -though, like synchronization operations, they cannot contribute to data races. -\end{note} - -\pnum -All modifications to a particular atomic object \placeholder{M} occur in some -particular total order, called the \defn{modification order} of \placeholder{M}. -\begin{note} There is a separate order for each -atomic object. There is no requirement that these can be combined into a single -total order for all objects. In general this will be impossible since different -threads may observe modifications to different objects in inconsistent orders. -\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 -\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} - -\pnum -Certain library calls \defn{synchronize with} other library calls performed by -another thread. For example, an atomic store-release synchronizes with a -load-acquire that takes its value from the store\iref{atomics.order}. -\begin{note} Except in the specified cases, reading a later value does not -necessarily ensure visibility as described below. Such a requirement would -sometimes interfere with efficient implementation. \end{note} \begin{note} The -specifications of the synchronization operations define when one reads the value -written by another. For atomic objects, the definition is clear. All operations -on a given mutex occur in a single total order. Each mutex acquisition ``reads -the value written'' by the last mutex release. \end{note} - -\pnum -An evaluation \placeholder{A} \defn{carries a dependency} to an evaluation \placeholder{B} if - -\begin{itemize} -\item -the value of \placeholder{A} is used as an operand of \placeholder{B}, unless: -\begin{itemize} -\item -\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}) -operator, or -\item -\placeholder{A} is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) -operator, or -\item -\placeholder{A} is the left operand of the built-in comma (\tcode{,}) -operator\iref{expr.comma}; \end{itemize} or -\item -\placeholder{A} writes a scalar object or bit-field \placeholder{M}, \placeholder{B} reads the value -written by \placeholder{A} from \placeholder{M}, and \placeholder{A} is sequenced before \placeholder{B}, or -\item -for some evaluation \placeholder{X}, \placeholder{A} carries a dependency to \placeholder{X}, and -\placeholder{X} carries a dependency to \placeholder{B}. -\end{itemize} -\begin{note} ``Carries a dependency to'' is a subset of ``is sequenced before'', -and is similarly strictly intra-thread. \end{note} - -\pnum -An evaluation \placeholder{A} is \defn{dependency-ordered before} an evaluation -\placeholder{B} if -\begin{itemize} -\item -\placeholder{A} performs a release operation on an atomic object \placeholder{M}, and, in -another thread, \placeholder{B} performs a consume operation on \placeholder{M} and reads a -value written by any -\indextext{side effects}% -side effect in the release sequence headed by \placeholder{A}, or - -\item -for some evaluation \placeholder{X}, \placeholder{A} is dependency-ordered before \placeholder{X} and -\placeholder{X} carries a dependency to \placeholder{B}. - -\end{itemize} -\begin{note} The relation ``is dependency-ordered before'' is analogous to -``synchronizes with'', but uses release/consume in place of release/acquire. -\end{note} - -\pnum -An evaluation \placeholder{A} \defn{inter-thread happens before} an evaluation \placeholder{B} -if -\begin{itemize} -\item - \placeholder{A} synchronizes with \placeholder{B}, or -\item - \placeholder{A} is dependency-ordered before \placeholder{B}, or -\item - for some evaluation \placeholder{X} - \begin{itemize} - \item - \placeholder{A} synchronizes with \placeholder{X} and \placeholder{X} - is sequenced before \placeholder{B}, or - \item - \placeholder{A} is sequenced before \placeholder{X} and \placeholder{X} - inter-thread happens before \placeholder{B}, or - \item - \placeholder{A} inter-thread happens before \placeholder{X} and \placeholder{X} - inter-thread happens before \placeholder{B}. - \end{itemize} -\end{itemize} -\begin{note} The ``inter-thread happens before'' relation describes arbitrary -concatenations of ``sequenced before'', ``synchronizes with'' and -``dependency-ordered before'' relationships, with two exceptions. The first -exception is that a concatenation is not permitted to end with -``dependency-ordered before'' followed by ``sequenced before''. The reason for -this limitation is that a consume operation participating in a -``dependency-ordered before'' relationship provides ordering only with respect -to operations to which this consume operation actually carries a dependency. The -reason that this limitation applies only to the end of such a concatenation is -that any subsequent release operation will provide the required ordering for a -prior consume operation. The second exception is that a concatenation is not -permitted to consist entirely of ``sequenced before''. The reasons for this -limitation are (1) to permit ``inter-thread happens before'' to be transitively -closed and (2) the ``happens before'' relation, defined below, provides for -relationships consisting entirely of ``sequenced before''. \end{note} - -\pnum -An evaluation \placeholder{A} \defn{happens before} an evaluation \placeholder{B} -(or, equivalently, \placeholder{B} \defn{happens after} \placeholder{A}) if: -\begin{itemize} -\item \placeholder{A} is sequenced before \placeholder{B}, or -\item \placeholder{A} inter-thread happens before \placeholder{B}. -\end{itemize} -The implementation shall ensure that no program execution demonstrates a cycle -in the ``happens before'' relation. \begin{note} This cycle would otherwise be -possible only through the use of consume operations. \end{note} - -\pnum -An evaluation \placeholder{A} \defn{strongly 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}. -\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. -\end{note} - -\pnum -A \defnx{visible side effect}{side effects!visible} \placeholder{A} on a scalar object or bit-field \placeholder{M} -with respect to a value computation \placeholder{B} of \placeholder{M} satisfies the -conditions: -\begin{itemize} -\item \placeholder{A} happens before \placeholder{B} and -\item there is no other -\indextext{side effects}% -side effect \placeholder{X} to \placeholder{M} such that \placeholder{A} -happens before \placeholder{X} and \placeholder{X} happens before \placeholder{B}. -\end{itemize} - -The value of a non-atomic scalar object or bit-field \placeholder{M}, as determined by -evaluation \placeholder{B}, shall be the value stored by the -\indextext{side effects!visible}% -visible side effect -\placeholder{A}. \begin{note} If there is ambiguity about which side effect to a -non-atomic object or bit-field is visible, then the behavior is either -unspecified or undefined. \end{note} \begin{note} This states that operations on -ordinary objects are not visibly reordered. This is not actually detectable -without data races, but it is necessary to ensure that data races, as defined -below, and with suitable restrictions on the use of atomics, correspond to data -races in a simple interleaved (sequentially consistent) execution. \end{note} - -\pnum -The value of an -atomic object \placeholder{M}, as determined by evaluation \placeholder{B}, shall be the value -stored by some -side effect \placeholder{A} that modifies \placeholder{M}, where \placeholder{B} does not happen -before \placeholder{A}. -\begin{note} -The set of such side effects is also restricted by the rest of the rules -described here, and in particular, by the coherence requirements below. -\end{note} - -\pnum -\indextext{coherence!write-write}% -If an operation \placeholder{A} that modifies an atomic object \placeholder{M} happens before -an operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall be earlier -than \placeholder{B} in the modification order of \placeholder{M}. \begin{note} This requirement -is known as write-write coherence. \end{note} - -\pnum -\indextext{coherence!read-read}% -If a -\indextext{value computation}% -value computation \placeholder{A} of an atomic object \placeholder{M} happens before a -value computation \placeholder{B} of \placeholder{M}, and \placeholder{A} takes its value from a side -effect \placeholder{X} on \placeholder{M}, then the value computed by \placeholder{B} shall either be -the value stored by \placeholder{X} or the value stored by a -\indextext{side effects}% -side effect \placeholder{Y} on -\placeholder{M}, where \placeholder{Y} follows \placeholder{X} in the modification order of \placeholder{M}. -\begin{note} This requirement is known as read-read coherence. \end{note} - -\pnum -\indextext{coherence!read-write}% -If a -\indextext{value computation}% -value computation \placeholder{A} of an atomic object \placeholder{M} happens before an -operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall take its value from a side -effect \placeholder{X} on \placeholder{M}, where \placeholder{X} precedes \placeholder{B} in the -modification order of \placeholder{M}. \begin{note} This requirement is known as -read-write coherence. \end{note} +\rSec1[intro.structure]{Structure of this document} \pnum -\indextext{coherence!write-read}% -If a -\indextext{side effects}% -side effect \placeholder{X} on an atomic object \placeholder{M} happens before a value -computation \placeholder{B} of \placeholder{M}, then the evaluation \placeholder{B} shall take its -value from \placeholder{X} or from a -\indextext{side effects}% -side effect \placeholder{Y} that follows \placeholder{X} in the -modification order of \placeholder{M}. \begin{note} This requirement is known as -write-read coherence. \end{note} +\indextext{standard!structure of|(}% +\indextext{standard!structure of}% +\ref{lex} through \ref{cpp} describe the \Cpp{} programming +language. That description includes detailed syntactic specifications in +a form described in~\ref{syntax}. For convenience, \ref{gram} +repeats all such syntactic specifications. \pnum -\begin{note} The four preceding coherence requirements effectively disallow -compiler reordering of atomic operations to a single object, even if both -operations are relaxed loads. This effectively makes the cache coherence -guarantee provided by most hardware available to \Cpp atomic operations. -\end{note} +\ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} +(the \defn{library clauses}) describe the \Cpp{} standard library. +That description includes detailed descriptions of the +entities and macros +that constitute the library, in a form described in \ref{library}. \pnum -\begin{note} The value observed by a load of an atomic depends on the ``happens -before'' relation, which depends on the values observed by loads of atomics. -The intended reading is that there must exist an -association of atomic loads with modifications they observe that, together with -suitably chosen modification orders and the ``happens before'' relation derived -as described above, satisfy the resulting constraints as imposed here. \end{note} +\ref{implimits} recommends lower bounds on the capacity of conforming +implementations. \pnum -Two actions are \defn{potentially concurrent} if -\begin{itemize} -\item they are performed by different threads, or -\item they are unsequenced, at least one is performed by a signal handler, and -they are not both performed by the same signal handler invocation. -\end{itemize} -The execution of a program contains a \defn{data race} if it contains two -potentially concurrent conflicting actions, at least one of which is not atomic, -and neither happens before the other, -except for the special case for signal handlers described below. -Any such data race results in undefined -behavior. \begin{note} It can be shown that programs that correctly use mutexes -and \tcode{memory_order_seq_cst} operations to prevent all data races and use no -other synchronization operations behave as if the operations executed by their -constituent threads were simply interleaved, with each -\indextext{value computation}% -value computation of an -object being taken from the last -\indextext{side effects}% -side effect on that object in that -interleaving. This is normally referred to as ``sequential consistency''. -However, this applies only to data-race-free programs, and data-race-free -programs cannot observe most program transformations that do not change -single-threaded program semantics. In fact, most single-threaded program -transformations continue to be allowed, since any program that behaves -differently as a result must perform an undefined operation. \end{note} +\ref{diff} summarizes the evolution of \Cpp{} since its first +published description, and explains in detail the differences between +\Cpp{} and C\@. Certain features of \Cpp{} exist solely for compatibility +purposes; \ref{depr} describes those features. \pnum -Two accesses to the same object of type \tcode{volatile std::sig_atomic_t} do not -result in a data race if both occur in the same thread, even if one or more -occurs in a signal handler. For each signal handler invocation, evaluations -performed by the thread invoking a signal handler can be divided into two -groups \placeholder{A} and \placeholder{B}, such that no evaluations in -\placeholder{B} happen before evaluations in \placeholder{A}, and the -evaluations of such \tcode{volatile std::sig_atomic_t} objects take values as though -all evaluations in \placeholder{A} happened before the execution of the signal -handler and the execution of the signal handler happened before all evaluations -in \placeholder{B}. +Throughout this document, each example is introduced by +``\noteintro{Example}'' and terminated by ``\noteoutro{example}''. Each note is +introduced by ``\noteintro{Note}'' and terminated by ``\noteoutro{note}''. Examples +and notes may be nested.% +\indextext{standard!structure of|)} -\pnum -\begin{note} Compiler transformations that introduce assignments to a potentially -shared memory location that would not be modified by the abstract machine are -generally precluded by this document, since such an assignment might overwrite -another assignment by a different thread in cases in which an abstract machine -execution would not have encountered a data race. This includes implementations -of data member assignment that overwrite adjacent members in separate memory -locations. Reordering of atomic loads in cases in which the atomics in question -may alias is also generally precluded, since this may violate the coherence -rules. \end{note} +\rSec1[syntax]{Syntax notation} \pnum -\begin{note} Transformations that introduce a speculative read of a potentially -shared memory location may not preserve the semantics of the \Cpp program as -defined in this document, since they potentially introduce a data race. However, -they are typically valid in the context of an optimizing compiler that targets a -specific machine with well-defined semantics for data races. They would be -invalid for a hypothetical machine that is not tolerant of races or provides -hardware race detection. \end{note} - -\rSec2[intro.progress]{Forward progress} +\indextext{notation!syntax|(}% +In the syntax notation used in this document, syntactic +categories are indicated by \grammarterm{italic} type, and literal words +and characters in \tcode{constant} \tcode{width} type. Alternatives are +listed on separate lines except in a few cases where a long set of +alternatives is marked by the phrase ``one of''. If the text of an alternative is too long to fit on a line, the text is continued on subsequent lines indented from the first one. +An optional terminal or non-terminal symbol is indicated by the subscript +``\opt{\relax}'', so -\pnum -The implementation may assume that any thread will eventually do one of the -following: -\begin{itemize} -\item terminate, -\item make a call to a library I/O function, -\item perform an access through a volatile glvalue, or -\item perform a synchronization operation or an atomic operation. -\end{itemize} -\begin{note} This is intended to allow compiler transformations such as removal of -empty loops, even when termination cannot be proven. \end{note} +\begin{ncbnf} +\terminal{\{} \opt{expression} \terminal{\}} +\end{ncbnf} -\pnum -Executions of atomic functions -that are either defined to be lock-free\iref{atomics.flag} -or indicated as lock-free\iref{atomics.lockfree} -are \defnx{lock-free executions}{lock-free execution}. -\begin{itemize} -\item - If there is only one thread that is not blocked\iref{defns.block} - in a standard library function, - a lock-free execution in that thread shall complete. - \begin{note} - Concurrently executing threads - may prevent progress of a lock-free execution. - For example, - this situation can occur - with load-locked store-conditional implementations. - This property is sometimes termed obstruction-free. - \end{note} -\item - When one or more lock-free executions run concurrently, - at least one should complete. - \begin{note} - It is difficult for some implementations - to provide absolute guarantees to this effect, - since repeated and particularly inopportune interference - from other threads - may prevent forward progress, - e.g., - by repeatedly stealing a cache line - for unrelated purposes - between load-locked and store-conditional instructions. - Implementations should ensure - that such effects cannot indefinitely delay progress - under expected operating conditions, - and that such anomalies - can therefore safely be ignored by programmers. - Outside this document, - this property is sometimes termed lock-free. - \end{note} -\end{itemize} +indicates an optional expression enclosed in braces.% \pnum -During the execution of a thread of execution, each of the following is termed -an \defn{execution step}: +Names for syntactic categories have generally been chosen according to +the following rules: \begin{itemize} -\item termination of the thread of execution, -\item performing an access through a volatile glvalue, or -\item completion of a call to a library I/O function, a - synchronization operation, or an atomic operation. -\end{itemize} - -\pnum -An invocation of a standard library function that blocks\iref{defns.block} -is considered to continuously execute execution steps while waiting for the -condition that it blocks on to be satisfied. -\begin{example} -A library I/O function that blocks until the I/O operation is complete can -be considered to continuously check whether the operation is complete. Each -such check might consist of one or more execution steps, for example using -observable behavior of the abstract machine. -\end{example} - -\pnum -\begin{note} -Because of this and the preceding requirement regarding what threads of execution -have to perform eventually, it follows that no thread of execution can execute -forever without an execution step occurring. -\end{note} - -\pnum -A thread of execution \defnx{makes progress}{make progress!thread} -when an execution step occurs or a -lock-free execution does not complete because there are other concurrent threads -that are not blocked in a standard library function (see above). - -\pnum -\indextext{forward progress guarantees!concurrent}% -For a thread of execution providing \defn{concurrent forward progress guarantees}, -the implementation ensures that the thread will eventually make progress for as -long as it has not terminated. -\begin{note} -This is required regardless of whether or not other threads of executions (if any) -have been or are making progress. To eventually fulfill this requirement means that -this will happen in an unspecified but finite amount of time. -\end{note} - -\pnum -It is \impldef{whether the thread that executes \tcode{main} and the threads created -by \tcode{std::thread} provide concurrent forward progress guarantees} whether the -implementation-created thread of execution that executes -\tcode{main}\iref{basic.start.main} and the threads of execution created by -\tcode{std::thread}\iref{thread.thread.class} provide concurrent forward progress -guarantees. -\begin{note} -General-purpose implementations should provide these guarantees. -\end{note} - -\pnum -\indextext{forward progress guarantees!parallel}% -For a thread of execution providing \defn{parallel forward progress guarantees}, -the implementation is not required to ensure that the thread will eventually make -progress if it has not yet executed any execution step; once this thread has -executed a step, it provides concurrent forward progress guarantees. - -\pnum -\begin{note} -This does not specify a requirement for when to start this thread of execution, -which will typically be specified by the entity that creates this thread of -execution. For example, a thread of execution that provides concurrent forward -progress guarantees and executes tasks from a set of tasks in an arbitrary order, -one after the other, satisfies the requirements of parallel forward progress for -these tasks. -\end{note} - -\pnum -\indextext{forward progress guarantees!weakly parallel}% -For a thread of execution providing \defn{weakly parallel forward progress -guarantees}, the implementation does not ensure that the thread will eventually -make progress. - -\pnum -\begin{note} -Threads of execution providing weakly parallel forward progress guarantees cannot -be expected to make progress regardless of whether other threads make progress or -not; however, blocking with forward progress guarantee delegation, as defined below, -can be used to ensure that such threads of execution make progress eventually. -\end{note} - -\pnum -Concurrent forward progress guarantees are stronger than parallel forward progress -guarantees, which in turn are stronger than weakly parallel forward progress -guarantees. -\begin{note} -For example, some kinds of synchronization between threads of execution may only -make progress if the respective threads of execution provide parallel forward progress -guarantees, but will fail to make progress under weakly parallel guarantees. -\end{note} - -\pnum -\indextext{forward progress guarantees!delegation of}% -When a thread of execution \placeholder{P} is specified to \defn{block with forward -progress guarantee delegation} on the completion of a set \placeholder{S} of threads -of execution, then throughout the whole time of \placeholder{P} being blocked on -\placeholder{S}, the implementation shall ensure that the forward progress guarantees -provided by at least one thread of execution in \placeholder{S} is at least as strong -as \placeholder{P}'s forward progress guarantees. -\begin{note} -It is unspecified which thread or threads of execution in \placeholder{S} are chosen -and for which number of execution steps. The strengthening is not permanent and -not necessarily in place for the rest of the lifetime of the affected thread of -execution. As long as \placeholder{P} is blocked, the implementation has to eventually -select and potentially strengthen a thread of execution in \placeholder{S}. -\end{note} -Once a thread of execution in \placeholder{S} terminates, it is removed from \placeholder{S}. -Once \placeholder{S} is empty, \placeholder{P} is unblocked. - -\pnum -\begin{note} -A thread of execution \placeholder{B} thus can temporarily provide an effectively -stronger forward progress guarantee for a certain amount of time, due to a -second thread of execution \placeholder{A} being blocked on it with forward -progress guarantee delegation. In turn, if \placeholder{B} then blocks with -forward progress guarantee delegation on \placeholder{C}, this may also temporarily -provide a stronger forward progress guarantee to \placeholder{C}. -\end{note} - -\pnum -\begin{note} -If all threads of execution in \placeholder{S} finish executing (e.g., they terminate -and do not use blocking synchronization incorrectly), then \placeholder{P}'s execution -of the operation that blocks with forward progress guarantee delegation will not -result in \placeholder{P}'s progress guarantee being effectively weakened. -\end{note} - -\pnum -\begin{note} -This does not remove any constraints regarding blocking synchronization for -threads of execution providing parallel or weakly parallel forward progress -guarantees because the implementation is not required to strengthen a particular -thread of execution whose too-weak progress guarantee is preventing overall progress. -\end{note} - -\pnum -An implementation should ensure that the last value (in modification order) -assigned by an atomic or synchronization operation will become visible to all -other threads in a finite period of time.% -\indextext{operation!atomic|)}% -\indextext{threads!multiple|)} +\item \grammarterm{X-name} is a use of an identifier in a context that +determines its meaning (e.g., \grammarterm{class-name}, +\grammarterm{typedef-name}). +\item \grammarterm{X-id} is an identifier with no context-dependent meaning +(e.g., \grammarterm{qualified-id}). +\item \grammarterm{X-seq} is one or more \grammarterm{X}'s without intervening +delimiters (e.g., \grammarterm{declaration-seq} is a sequence of +declarations). +\item \grammarterm{X-list} is one or more \grammarterm{X}'s separated by +intervening commas (e.g., \grammarterm{identifier-list} is a sequence of +identifiers separated by commas). +\end{itemize}% +\indextext{notation!syntax|)} \rSec1[intro.ack]{Acknowledgments} \pnum -The \Cpp programming language as described in this document +The \Cpp{} programming language as described in this document is based on the language as described in Chapter R (Reference -Manual) of Stroustrup: \doccite{The \Cpp Programming Language} (second +Manual) of Stroustrup: \doccite{The \Cpp{} Programming Language} (second edition, Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright \copyright 1991 AT\&T). That, in turn, is based on the C programming language as described in Appendix A of Kernighan and @@ -1750,7 +663,7 @@ \pnum Portions of the library Clauses of this document are based on work by P.J. Plauger, which was published as \doccite{The Draft -Standard \Cpp Library} (Prentice-Hall, ISBN 0-13-117003-1, copyright +Standard \Cpp{} Library} (Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.J. Plauger). \pnum diff --git a/source/iostreams.tex b/source/iostreams.tex index f084a61eab..688f2ed2ef 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4,7 +4,7 @@ \rSec1[input.output.general]{General} \pnum -This Clause describes components that \Cpp programs may use to perform +This Clause describes components that \Cpp{} programs may use to perform input/output operations. \pnum @@ -31,6 +31,7 @@ & & \tcode{} \\ \rowsep \ref{string.streams} & String streams & \tcode{} \\ \rowsep \ref{file.streams} & File streams & \tcode{} \\ \rowsep +\ref{syncstream} & Synchronized output streams & \tcode{} \\ \rowsep \ref{filesystems} & File systems & \tcode{} \\ \rowsep \ref{c.files} & C library files & \tcode{} \\ & & \tcode{} \\ @@ -39,7 +40,7 @@ \pnum Figure~\ref{fig:streampos} illustrates relationships among various types described in this clause. A line from \textbf{A} to \textbf{B} indicates that \textbf{A} -is an alias (e.g. a typedef) for \textbf{B} or that \textbf{A} is defined in terms of +is an alias (e.g., a typedef) for \textbf{B} or that \textbf{A} is defined in terms of \textbf{B}. \begin{importgraphic} @@ -116,8 +117,7 @@ \rSec1[iostream.forward]{Forward declarations} \rSec2[iosfwd.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{iosfwd}}% -\indexlibrary{\idxhdr{iosfwd}}% +\indexhdr{iosfwd}% \indexlibrary{\idxcode{basic_ios}}% \indexlibrary{\idxcode{basic_streambuf}}% @@ -133,6 +133,8 @@ \indexlibrary{\idxcode{basic_fstream}}% \indexlibrary{\idxcode{basic_istreambuf_iterator}}% \indexlibrary{\idxcode{basic_ostreambuf_iterator}}% +\indexlibrary{\idxcode{basic_syncbuf}}% +\indexlibrary{\idxcode{basic_osyncstream}}% \indexlibrary{\idxcode{ios}}% \indexlibrary{\idxcode{streambuf}}% \indexlibrary{\idxcode{istream}}% @@ -156,6 +158,10 @@ \indexlibrary{\idxcode{wifstream}}% \indexlibrary{\idxcode{wofstream}}% \indexlibrary{\idxcode{wfstream}}% +\indexlibrary{\idxcode{syncbuf}}% +\indexlibrary{\idxcode{wsyncbuf}}% +\indexlibrary{\idxcode{osyncstream}}% +\indexlibrary{\idxcode{wosyncstream}}% \begin{codeblock} namespace std { template class char_traits; @@ -166,42 +172,49 @@ template class allocator; - template > + template> class basic_ios; - template > + template> class basic_streambuf; - template > + template> class basic_istream; - template > + template> class basic_ostream; - template > + template> class basic_iostream; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringbuf; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_istringstream; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_ostringstream; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringstream; - template > + template> class basic_filebuf; - template > + template> class basic_ifstream; - template > + template> class basic_ofstream; - template > + template> class basic_fstream; - template > + template, + class Allocator = allocator> + class basic_syncbuf; + template, + class Allocator = allocator> + class basic_osyncstream; + + template> class istreambuf_iterator; - template > + template> class ostreambuf_iterator; using ios = basic_ios; @@ -222,6 +235,9 @@ using ofstream = basic_ofstream; using fstream = basic_fstream; + using syncbuf = basic_syncbuf; + using osyncstream = basic_osyncstream; + using wstreambuf = basic_streambuf; using wistream = basic_istream; using wostream = basic_ostream; @@ -237,7 +253,10 @@ using wofstream = basic_ofstream; using wfstream = basic_fstream; - template class fpos; + using wsyncbuf = basic_syncbuf; + using wosyncstream = basic_osyncstream; + + template class fpos; using streampos = fpos::state_type>; using wstreampos = fpos::state_type>; } @@ -363,8 +382,7 @@ \rSec1[iostream.objects]{Standard iostream objects} \rSec2[iostream.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{iostream}}% -\indexlibrary{\idxhdr{iostream}}% +\indexhdr{iostream}% \begin{codeblock} #include // see \ref{ios.syn} @@ -392,8 +410,7 @@ the type \tcode{FILE} declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \pnum @@ -403,7 +420,7 @@ standard C streams provided for by the functions declared in \tcode{}\iref{c.files}, and includes all the headers necessary to use these objects. -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \pnum The objects are constructed and the associations are established at some @@ -449,8 +466,7 @@ associated with the object \tcode{stdin}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \pnum @@ -477,8 +493,7 @@ associated with the object \tcode{stdout}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \end{itemdescr} @@ -495,8 +510,7 @@ associated with the object \tcode{stderr}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \pnum @@ -522,8 +536,7 @@ associated with the object \tcode{stderr}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \end{itemdescr} @@ -542,8 +555,7 @@ associated with the object \tcode{stdin}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \pnum @@ -570,8 +582,7 @@ associated with the object \tcode{stdout}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \end{itemdescr} @@ -588,8 +599,7 @@ associated with the object \tcode{stderr}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \pnum @@ -615,16 +625,14 @@ associated with the object \tcode{stderr}, declared in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}. \end{itemdescr} \rSec1[iostreams.base]{Iostreams base classes} \rSec2[ios.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{ios}}% -\indexlibrary{\idxhdr{ios}}% +\indexhdr{ios}% \indexlibrary{\idxcode{io_errc}}% \begin{codeblock} @@ -633,10 +641,10 @@ namespace std { using streamoff = @\impdef@; using streamsize = @\impdef@; - template class fpos; + template class fpos; class ios_base; - template > + template> class basic_ios; // \ref{std.ios.manip}, manipulators @@ -682,7 +690,7 @@ stream = 1 }; - template <> struct is_error_code_enum : public true_type { }; + template<> struct is_error_code_enum : public true_type { }; error_code make_error_code(io_errc e) noexcept; error_condition make_error_condition(io_errc e) noexcept; const error_category& iostream_category() noexcept; @@ -809,10 +817,10 @@ long& iword(int index); void*& pword(int index); - // destructor: + // destructor virtual ~ios_base(); - // \ref{ios.base.callback}, callbacks; + // \ref{ios.base.callback}, callbacks enum event { erase_event, imbue_event, copyfmt_event }; using event_callback = void (*)(event, ios_base&, int index); void register_callback(event_callback fn, int index); @@ -1347,7 +1355,7 @@ \begin{itemdescr} \pnum \returns -If no locale has been imbued, a copy of the global \Cpp locale, +If no locale has been imbued, a copy of the global \Cpp{} locale, \tcode{locale()}, in effect at the time of construction. Otherwise, returns the imbued locale, to be used to @@ -1611,7 +1619,7 @@ \indexlibrary{\idxcode{fpos}}% \begin{codeblock} namespace std { - template class fpos { + template class fpos { public: // \ref{fpos.members}, members stateT state() const; @@ -1756,7 +1764,7 @@ \indexlibrary{\idxcode{basic_ios}}% \begin{codeblock} namespace std { - template > + template> class basic_ios : public ios_base { public: using char_type = charT; @@ -2054,11 +2062,11 @@ \tcode{*this} the corresponding member objects of \tcode{rhs} as follows: -\begin{enumerate} +\begin{itemize} \item calls each registered callback pair \tcode{(fn, index)} as \tcode{(*fn)(erase_event, *this, index)}; -\item assigns to the member objects of \tcode{*this} the corresponding member objects of +\item then, assigns to the member objects of \tcode{*this} the corresponding member objects of \tcode{rhs}, except that \begin{itemize} @@ -2075,12 +2083,12 @@ objects; \end{itemize} -\item calls each callback pair that was copied from \tcode{rhs} as +\item then, calls each callback pair that was copied from \tcode{rhs} as \tcode{(*fn)(copyfmt_event, *this, index)}; -\item calls \tcode{exceptions(rhs.exceptions())}. +\item then, calls \tcode{exceptions(rhs.exceptions())}. -\end{enumerate} +\end{itemize} \pnum \begin{note} @@ -2721,7 +2729,7 @@ \pnum \begin{note} The more obvious use of \tcode{ios_base::hex} to specify hexadecimal floating-point format would -change the meaning of existing well-defined programs. \CppIII +change the meaning of existing well-defined programs. \CppIII{} gives no meaning to the combination of \tcode{fixed} and \tcode{scientific}.\end{note} @@ -2779,8 +2787,7 @@ \rSec1[stream.buffers]{Stream buffers} \rSec2[streambuf.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{streambuf}}% -\indexlibrary{\idxhdr{streambuf}}% +\indexhdr{streambuf}% \indexlibrary{\idxcode{streambuf}}% \indexlibrary{\idxcode{basic_streambuf}}% @@ -2788,7 +2795,7 @@ \indexlibrary{\idxcode{basic_streambuf}}% \begin{codeblock} namespace std { - template > + template> class basic_streambuf; using streambuf = basic_streambuf; using wstreambuf = basic_streambuf; @@ -2907,7 +2914,7 @@ \indexlibrary{\idxcode{basic_streambuf}}% \begin{codeblock} namespace std { - template > + template> class basic_streambuf { public: using char_type = charT; @@ -2932,7 +2939,7 @@ = ios_base::in | ios_base::out); int pubsync(); - // Get and put areas + // get and put areas // \ref{streambuf.pub.get}, get area streamsize in_avail(); int_type snextc(); @@ -3964,10 +3971,10 @@ \requires Every overriding definition of this virtual function shall obey the following constraints: -\begin{enumerate} +\begin{itemize} \item The effect of consuming a character on the associated output sequence is -specified\footnote{That is, for each class derived from an instance of +specified.\footnote{That is, for each class derived from an instance of \tcode{basic_streambuf} in this Clause~(\ref{stringbuf}, \ref{filebuf}), @@ -4006,7 +4013,7 @@ and \tcode{pptr()} according to the above rules. -\end{enumerate} +\end{itemize} \pnum \returns @@ -4035,27 +4042,26 @@ \rSec1[iostream.format]{Formatting and manipulators} \rSec2[istream.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{istream}}% -\indexlibrary{\idxhdr{istream}}% +\indexhdr{istream}% \begin{codeblock} namespace std { - template > + template> class basic_istream; using istream = basic_istream; using wistream = basic_istream; - template > + template> class basic_iostream; using iostream = basic_iostream; using wiostream = basic_iostream; - template + template basic_istream& ws(basic_istream& is); - template + template basic_istream& operator>>(basic_istream&& is, T&& x); } \end{codeblock} @@ -4066,25 +4072,24 @@ \indexlibrary{\idxcode{basic_istream}}% \rSec2[ostream.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{ostream}}% -\indexlibrary{\idxhdr{ostream}}% +\indexhdr{ostream}% \begin{codeblock} namespace std { - template > + template> class basic_ostream; using ostream = basic_ostream; using wostream = basic_ostream; - template + template basic_ostream& endl(basic_ostream& os); - template + template basic_ostream& ends(basic_ostream& os); - template + template basic_ostream& flush(basic_ostream& os); - template + template basic_ostream& operator<<(basic_ostream&& os, const T& x); } \end{codeblock} @@ -4095,8 +4100,7 @@ \indexlibrary{\idxcode{basic_ostream}}% \rSec2[iomanip.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{iomanip}}% -\indexlibrary{\idxhdr{iomanip}}% +\indexhdr{iomanip}% \begin{codeblock} namespace std { @@ -4107,23 +4111,23 @@ template @\textit{T4}@ setfill(charT c); @\textit{T5}@ setprecision(int n); @\textit{T6}@ setw(int n); - template @\textit{T7}@ get_money(moneyT& mon, bool intl = false); - template @\textit{T8}@ put_money(const moneyT& mon, bool intl = false); - template @\textit{T9}@ get_time(struct tm* tmb, const charT* fmt); - template @\textit{T10}@ put_time(const struct tm* tmb, const charT* fmt); + template @\textit{T7}@ get_money(moneyT& mon, bool intl = false); + template @\textit{T8}@ put_money(const moneyT& mon, bool intl = false); + template @\textit{T9}@ get_time(struct tm* tmb, const charT* fmt); + template @\textit{T10}@ put_time(const struct tm* tmb, const charT* fmt); - template + template @\textit{T11}@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); - template + template @\textit{T12}@ quoted(const basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); - template + template @\textit{T13}@ quoted(basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); - template + template @\textit{T14}@ quoted(basic_string_view s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); } @@ -4142,10 +4146,10 @@ \indexlibrary{\idxcode{basic_istream}}% \begin{codeblock} namespace std { - template > + template> class basic_istream : virtual public basic_ios { public: - // types (inherited from \tcode{basic_ios}\iref{ios}): + // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; @@ -4373,7 +4377,7 @@ \indexlibrary{\idxcode{sentry}!\idxcode{basic_istream}}% \begin{codeblock} namespace std { - template > + template> class basic_istream::sentry { using traits_type = traits; bool ok_; // \expos @@ -5524,7 +5528,7 @@ \indexlibrary{\idxcode{ws}}% \begin{itemdecl} -template +template basic_istream& ws(basic_istream& is); \end{itemdecl} @@ -5553,7 +5557,7 @@ \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} -template +template basic_istream& operator>>(basic_istream&& is, T&& x); \end{itemdecl} @@ -5575,7 +5579,7 @@ \indexlibrary{\idxcode{basic_iostream}}% \begin{codeblock} namespace std { - template > + template> class basic_iostream : public basic_istream, public basic_ostream { @@ -5702,10 +5706,10 @@ \indexlibrary{\idxcode{basic_ostream}}% \begin{codeblock} namespace std { - template > + template> class basic_ostream : virtual public basic_ios { public: - // types (inherited from \tcode{basic_ios}\iref{ios}): + // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; @@ -5918,7 +5922,7 @@ \indexlibrary{\idxcode{sentry}!\idxcode{basic_ostream}}% \begin{codeblock} namespace std { - template > + template> class basic_ostream::sentry { bool ok_; // \expos public: @@ -6595,7 +6599,7 @@ \indexlibrary{\idxcode{endl}}% \begin{itemdecl} -template +template basic_ostream& endl(basic_ostream& os); \end{itemdecl} @@ -6614,7 +6618,7 @@ \indexlibrary{\idxcode{ends}}% \begin{itemdecl} -template +template basic_ostream& ends(basic_ostream& os); \end{itemdecl} @@ -6632,7 +6636,7 @@ \indexlibrary{\idxcode{flush}}% \begin{itemdecl} -template +template basic_ostream& flush(basic_ostream& os); \end{itemdecl} @@ -6651,7 +6655,7 @@ \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream&& os, const T& x); \end{itemdecl} @@ -6940,7 +6944,7 @@ \indexlibrary{\idxcode{get_money}}% \begin{itemdecl} -template @\unspec@ get_money(moneyT& mon, bool intl = false); +template @\unspec@ get_money(moneyT& mon, bool intl = false); \end{itemdecl} \begin{itemdescr} @@ -6959,7 +6963,7 @@ \tcode{f(in, mon, intl)}, where the function \tcode{f} is defined as: \begin{codeblock} -template +template void f(basic_ios& str, moneyT& mon, bool intl) { using Iter = istreambuf_iterator; using MoneyGet = money_get; @@ -6980,7 +6984,7 @@ \indexlibrary{\idxcode{put_money}}% \begin{itemdecl} -template @\unspec@ put_money(const moneyT& mon, bool intl = false); +template @\unspec@ put_money(const moneyT& mon, bool intl = false); \end{itemdecl} \begin{itemdescr} @@ -6996,7 +7000,7 @@ \tcode{f(out, mon, intl)}, where the function \tcode{f} is defined as: \begin{codeblock} -template +template void f(basic_ios& str, const moneyT& mon, bool intl) { using Iter = ostreambuf_iterator; using MoneyPut = money_put; @@ -7016,7 +7020,7 @@ \indexlibrary{\idxcode{get_time}}% \begin{itemdecl} -template @\unspec@ get_time(struct tm* tmb, const charT* fmt); +template @\unspec@ get_time(struct tm* tmb, const charT* fmt); \end{itemdecl} \begin{itemdescr} @@ -7031,7 +7035,7 @@ defined as: \begin{codeblock} -template +template void f(basic_ios& str, struct tm* tmb, const charT* fmt) { using Iter = istreambuf_iterator; using TimeGet = time_get; @@ -7053,7 +7057,7 @@ \indexlibrary{\idxcode{put_time}}% \begin{itemdecl} -template @\unspec@ put_time(const struct tm* tmb, const charT* fmt); +template @\unspec@ put_time(const struct tm* tmb, const charT* fmt); \end{itemdecl} \begin{itemdescr} @@ -7070,7 +7074,7 @@ where the function \tcode{f} is defined as: \begin{codeblock} -template +template void f(basic_ios& str, const struct tm* tmb, const charT* fmt) { using Iter = ostreambuf_iterator; using TimePut = time_put; @@ -7095,12 +7099,12 @@ \indexlibrary{\idxcode{quoted}}% \begin{itemdecl} -template +template @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); -template +template @\unspec@ quoted(const basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); -template +template @\unspec@ quoted(basic_string_view s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); \end{itemdecl} @@ -7133,7 +7137,7 @@ \indexlibrary{\idxcode{quoted}}% \begin{itemdecl} -template +template @\unspec@ quoted(basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); \end{itemdecl} @@ -7180,8 +7184,7 @@ \rSec1[string.streams]{String-based streams} \rSec2[sstream.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{sstream}}% -\indexlibrary{\idxhdr{sstream}}% +\indexhdr{sstream}% \indexlibrary{\idxcode{stringbuf}}% \indexlibrary{\idxcode{basic_stringbuf}}% @@ -7201,28 +7204,28 @@ \indexlibrary{\idxcode{basic_stringstream}}% \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringbuf; using stringbuf = basic_stringbuf; using wstringbuf = basic_stringbuf; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_istringstream; using istringstream = basic_istringstream; using wistringstream = basic_istringstream; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_ostringstream; using ostringstream = basic_ostringstream; using wostringstream = basic_ostringstream; - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringstream; using stringstream = basic_stringstream; using wstringstream = basic_stringstream; @@ -7243,8 +7246,8 @@ \indexlibrary{\idxcode{basic_stringbuf}}% \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringbuf : public basic_streambuf { public: using char_type = charT; @@ -7290,7 +7293,7 @@ ios_base::openmode mode; // \expos }; - template + template void swap(basic_stringbuf& x, basic_stringbuf& y); } @@ -7428,7 +7431,7 @@ \indexlibrarymember{swap}{basic_stringbuf}% \begin{itemdecl} -template +template void swap(basic_stringbuf& x, basic_stringbuf& y); \end{itemdecl} @@ -7763,8 +7766,8 @@ \indexlibrary{\idxcode{basic_istringstream}}% \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_istringstream : public basic_istream { public: using char_type = charT; @@ -7797,7 +7800,7 @@ basic_stringbuf sb; // \expos }; - template + template void swap(basic_istringstream& x, basic_istringstream& y); } @@ -7899,7 +7902,7 @@ \indexlibrarymember{swap}{basic_istringstream}% \begin{itemdecl} -template +template void swap(basic_istringstream& x, basic_istringstream& y); \end{itemdecl} @@ -7950,8 +7953,8 @@ \indexlibrary{\idxcode{basic_ostringstream}}% \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_ostringstream : public basic_ostream { public: using char_type = charT; @@ -7984,7 +7987,7 @@ basic_stringbuf sb; // \expos }; - template + template void swap(basic_ostringstream& x, basic_ostringstream& y); } @@ -8087,7 +8090,7 @@ \indexlibrarymember{swap}{basic_ostringstream}% \begin{itemdecl} -template +template void swap(basic_ostringstream& x, basic_ostringstream& y); \end{itemdecl} @@ -8138,8 +8141,8 @@ \indexlibrary{\idxcode{basic_stringstream}}% \begin{codeblock} namespace std { - template , - class Allocator = allocator> + template, + class Allocator = allocator> class basic_stringstream : public basic_iostream { public: using char_type = charT; @@ -8172,7 +8175,7 @@ basic_stringbuf sb; // \expos }; - template + template void swap(basic_stringstream& x, basic_stringstream& y); } @@ -8280,7 +8283,7 @@ \indexlibrarymember{swap}{basic_stringstream}% \begin{itemdecl} -template +template void swap(basic_stringstream& x, basic_stringstream& y); \end{itemdecl} @@ -8329,8 +8332,7 @@ \rSec1[file.streams]{File-based streams} \rSec2[fstream.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{fstream}}% -\indexlibrary{\idxhdr{fstream}}% +\indexhdr{fstream}% \indexlibrary{\idxcode{filebuf}}% \indexlibrary{\idxcode{basic_filebuf}}% \indexlibrary{\idxcode{wfilebuf}}% @@ -8349,22 +8351,22 @@ \indexlibrary{\idxcode{basic_fstream}}% \begin{codeblock} namespace std { - template > + template> class basic_filebuf; using filebuf = basic_filebuf; using wfilebuf = basic_filebuf; - template > + template> class basic_ifstream; using ifstream = basic_ifstream; using wifstream = basic_ifstream; - template > + template> class basic_ofstream; using ofstream = basic_ofstream; using wofstream = basic_ofstream; - template > + template> class basic_fstream; using fstream = basic_fstream; using wfstream = basic_fstream; @@ -8397,7 +8399,7 @@ \indexlibrary{\idxcode{basic_filebuf}}% \begin{codeblock} namespace std { - template > + template> class basic_filebuf : public basic_streambuf { public: using char_type = charT; @@ -8448,7 +8450,7 @@ void imbue(const locale& loc) override; }; - template + template void swap(basic_filebuf& x, basic_filebuf& y); } @@ -8493,7 +8495,7 @@ \pnum In order to support file I/O and multibyte/wide character conversion, conversions are performed using members of a facet, referred to as -\tcode{a_codecvt} in following sections, obtained as if by +\tcode{a_codecvt} in following subclauses, obtained as if by \begin{codeblock} const codecvt& a_codecvt = @@ -8606,7 +8608,7 @@ \indexlibrarymember{swap}{basic_filebuf}% \begin{itemdecl} -template +template void swap(basic_filebuf& x, basic_filebuf& y); \end{itemdecl} @@ -8651,12 +8653,12 @@ \tcode{filebuf} as required. It then opens a file, if possible, whose name is the -\ntbs \tcode{s} +\ntbs{} \tcode{s} (as if by calling \tcode{fopen(s, modstr)}). \indextext{NTBS}% \indexlibrary{\idxcode{fopen}}% -The \ntbs \tcode{modstr} is determined from +The \ntbs{} \tcode{modstr} is determined from \tcode{mode \& \~{}ios_base::ate} as indicated in Table~\ref{tab:iostreams.file.open.modes}. If \tcode{mode} is not some combination of flags shown in the table then @@ -8701,8 +8703,7 @@ \tcode{fseek(FILE*, long, int)} \indexlibrary{\idxcode{fseek}}% are declared, in -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \tcode{}\iref{cstdio.syn}.} \pnum @@ -9167,7 +9168,7 @@ \indexlibrary{\idxcode{basic_ifstream}}% \begin{codeblock} namespace std { - template > + template> class basic_ifstream : public basic_istream { public: using char_type = charT; @@ -9208,7 +9209,7 @@ basic_filebuf sb; // \expos }; - template + template void swap(basic_ifstream& x, basic_ifstream& y); } @@ -9328,7 +9329,7 @@ \indexlibrarymember{swap}{basic_ifstream}% \begin{itemdecl} -template +template void swap(basic_ifstream& x, basic_ifstream& y); \end{itemdecl} @@ -9416,7 +9417,7 @@ \indexlibrary{\idxcode{basic_ofstream}}% \begin{codeblock} namespace std { - template > + template> class basic_ofstream : public basic_ostream { public: using char_type = charT; @@ -9457,7 +9458,7 @@ basic_filebuf sb; // \expos }; - template + template void swap(basic_ofstream& x, basic_ofstream& y); } @@ -9576,7 +9577,7 @@ \indexlibrarymember{swap}{basic_ofstream}% \begin{itemdecl} -template +template void swap(basic_ofstream& x, basic_ofstream& y); \end{itemdecl} @@ -9662,7 +9663,7 @@ \indexlibrary{\idxcode{basic_fstream}}% \begin{codeblock} namespace std { - template > + template> class basic_fstream : public basic_iostream { public: using char_type = charT; @@ -9677,7 +9678,7 @@ const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( - const std::filesystem::path::value_type* s, + const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} explicit basic_fstream( const string& s, @@ -9700,7 +9701,7 @@ const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( - const std::filesystem::path::value_type* s, + const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} void open( const string& s, @@ -9714,7 +9715,7 @@ basic_filebuf sb; // \expos }; - template + template void swap(basic_fstream& x, basic_fstream& y); } @@ -9841,7 +9842,7 @@ \indexlibrarymember{swap}{basic_fstream}% \begin{itemdecl} -template +template void swap(basic_fstream& x, basic_fstream& y); \end{itemdecl} @@ -9930,6 +9931,592 @@ \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} +\rSec1[syncstream]{Synchronized output streams} + +\rSec2[syncstream.syn]{Header \tcode{} synopsis} +\indexhdr{syncstream}% + +\indexlibrary{\idxcode{syncbuf}}% +\indexlibrary{\idxcode{wsyncbuf}}% +\indexlibrary{\idxcode{osyncstream}}% +\indexlibrary{\idxcode{wosyncstream}}% +\begin{codeblock} +namespace std { + template + class basic_syncbuf; + + using syncbuf = basic_syncbuf; + using wsyncbuf = basic_syncbuf; + + template + class basic_osyncstream; + + using osyncstream = basic_osyncstream; + using wosyncstream = basic_osyncstream; +} +\end{codeblock} + +\pnum +The header \tcode{} provides a mechanism +to synchronize execution agents writing to the same stream. + +\rSec2[syncstream.syncbuf]{Class template \tcode{basic_syncbuf}} + +\rSec3[syncstream.syncbuf.overview]{Overview} + +\indexlibrary{\idxcode{basic_syncbuf}}% +\begin{codeblock} +namespace std { + template + class basic_syncbuf : public basic_streambuf { + public: + using char_type = charT; + using int_type = typename traits::int_type; + using pos_type = typename traits::pos_type; + using off_type = typename traits::off_type; + using traits_type = traits; + using allocator_type = Allocator; + + using streambuf_type = basic_streambuf; + + // \ref{syncstream.syncbuf.cons}, construction and destruction + explicit basic_syncbuf(streambuf_type* obuf = nullptr) + : basic_syncbuf(obuf, Allocator()) {} + basic_syncbuf(streambuf_type*, const Allocator&); + basic_syncbuf(basic_syncbuf&&); + ~basic_syncbuf(); + + // \ref{syncstream.syncbuf.assign}, assignment and swap + basic_syncbuf& operator=(basic_syncbuf&&); + void swap(basic_syncbuf&); + + // \ref{syncstream.syncbuf.members}, member functions + bool emit(); + streambuf_type* get_wrapped() const noexcept; + allocator_type get_allocator() const noexcept; + void set_emit_on_sync(bool) noexcept; + + protected: + // \ref{syncstream.syncbuf.virtuals}, overridden virtual functions + int sync() override; + + private: + streambuf_type* wrapped; // \expos + bool emit_on_sync{}; // \expos + }; + + // \ref{syncstream.syncbuf.special}, specialized algorithms + template + void swap(basic_syncbuf&, + basic_syncbuf&); +} +\end{codeblock} + +\pnum +Class template \tcode{basic_syncbuf} stores character data +written to it, known as the associated output, into internal +buffers allocated using the object's allocator. +The associated output is transferred to the +wrapped stream buffer object \tcode{*wrapped} +when \tcode{emit()} is called +or when the \tcode{basic_syncbuf} object is destroyed. +Such transfers are atomic with respect to transfers +by other \tcode{basic_syncbuf} objects +with the same wrapped stream buffer object. + +\rSec3[syncstream.syncbuf.cons]{Construction and destruction} + +\indexlibrary{\idxcode{basic_syncbuf}!constructor}% +\begin{itemdecl} +basic_syncbuf(streambuf_type* obuf, const Allocator& allocator); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs the \tcode{basic_syncbuf} object and +sets \tcode{wrapped} to \tcode{obuf}. + +\pnum +\remarks +A copy of \tcode{allocator} is used +to allocate memory for internal buffers +holding the associated output. + +\pnum +\throws +Nothing unless an exception is thrown +by the construction of a mutex or +by memory allocation. + +\pnum +\postconditions +\tcode{get_wrapped() == obuf} and +\tcode{get_allocator() == allocator} are \tcode{true}. +\end{itemdescr} + +\indexlibrary{\idxcode{basic_syncbuf}!constructor}% +\begin{itemdecl} +basic_syncbuf(basic_syncbuf&& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Move constructs from \tcode{other} (Table~\ref{tab:moveconstructible}). + +\pnum +\postconditions +The value returned by \tcode{this->get_wrapped()} +is the value returned by \tcode{other.get_wrapped()} +prior to calling this constructor. +Output stored in \tcode{other} +prior to calling this constructor +will be stored in \tcode{*this} afterwards. +\tcode{other.rdbuf()->pbase() == other.rdbuf()->pptr()} +and +\tcode{other.get_wrapped() == nullptr} +are \tcode{true}. + +\pnum +\remarks +This constructor disassociates \tcode{other} +from its wrapped stream buffer, +ensuring destruction of \tcode{other} produces no output. +\end{itemdescr} + +\indexlibrary{\idxcode{basic_syncbuf}!destructor}% +\begin{itemdecl} +~basic_syncbuf(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{emit()}. + +\pnum +\throws +Nothing. +If an exception is thrown from \tcode{emit()}, +the destructor catches and ignores that exception. +\end{itemdescr} + +\rSec3[syncstream.syncbuf.assign]{Assignment and swap} + +\indexlibrarymember{operator=}{basic_syncbuf}% +\begin{itemdecl} +basic_syncbuf& operator=(basic_syncbuf&& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{emit()} then +move assigns from \tcode{rhs}. +After the move assignment \tcode{*this} +has the observable state it would have had if +it had been move constructed from \tcode{rhs}\iref{syncstream.syncbuf.cons}. + +\pnum +\returns +\tcode{*this}. + +\pnum +\postconditions +\begin{itemize} +\item +\tcode{rhs.get_wrapped() == nullptr} is \tcode{true}. +\item +\tcode{this->get_allocator() == rhs.get_allocator()} is \tcode{true} when +\begin{codeblock} +allocator_traits::propagate_on_container_move_assignment::value +\end{codeblock} +is \tcode{true}; otherwise, the allocator is unchanged. +\end{itemize} + +\pnum +\remarks +This assignment operator disassociates \tcode{rhs} +from its wrapped stream buffer, +ensuring destruction of \tcode{rhs} produces no output. +\end{itemdescr} + +\indexlibrarymember{swap}{basic_syncbuf}% +\begin{itemdecl} +void swap(basic_syncbuf& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Either +\tcode{allocator_traits::propagate_on_container_swap::value} +is \tcode{true} +or +\tcode{this->get_allocator() == other.get_allocator()} +is \tcode{true}. + +\pnum +\effects +Exchanges the state of \tcode{*this} and \tcode{other}. +\end{itemdescr} + +\rSec3[syncstream.syncbuf.members]{Member functions} + +\indexlibrarymember{emit}{basic_syncbuf}% +\begin{itemdecl} +bool emit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Atomically transfers the associated output of \tcode{*this} +to the stream buffer \tcode{*wrapped}, +so that it appears in the output stream +as a contiguous sequence of characters. +\tcode{wrapped->pubsync()} is called +if and only if a call was made to \tcode{sync()} +since the most recent call to \tcode{emit()}, if any. + +\pnum +\returns +\tcode{true} if all of the following conditions hold; +otherwise \tcode{false}: +\begin{itemize} +\item \tcode{wrapped == nullptr} is \tcode{false}. +\item All of the characters in the associated output were successfully transferred. +\item The call to \tcode{wrapped->pubsync()} (if any) succeeded. +\end{itemize} + +\pnum +\postconditions +On success, the associated output is empty. + +\pnum +\sync +All \tcode{emit()} calls transferring characters +to the same stream buffer object +appear to execute in a total order +consistent with the ``happens before'' relation\iref{intro.races}, +where each \tcode{emit()} call +synchronizes with +subsequent \tcode{emit()} calls in that total order. + +\pnum +\remarks +May call member functions of \tcode{wrapped} +while holding a lock uniquely associated with \tcode{wrapped}. +\end{itemdescr} + +\indexlibrarymember{get_wrapped}{basic_syncbuf}% +\begin{itemdecl} +streambuf_type* get_wrapped() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{wrapped}. +\end{itemdescr} + +\indexlibrarymember{get_allocator}{basic_syncbuf}% +\begin{itemdecl} +allocator_type get_allocator() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A copy of the allocator that was set in the constructor or assignment operator. +\end{itemdescr} + +\indexlibrarymember{set_emit_on_sync}{basic_syncbuf}% +\begin{itemdecl} +void set_emit_on_sync(bool b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\tcode{emit_on_sync = b}. +\end{itemdescr} + +\rSec3[syncstream.syncbuf.virtuals]{Overridden virtual functions} + +\indexlibrarymember{sync}{basic_syncbuf}% +\begin{itemdecl} +int sync() override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Records that the wrapped stream buffer is to be flushed. +Then, if \tcode{emit_on_sync} is \tcode{true}, calls \tcode{emit()}. +\begin{note} +If \tcode{emit_on_sync} is \tcode{false}, +the actual flush is delayed until a call to \tcode{emit()}. +\end{note} + +\pnum +\returns +If \tcode{emit()} was called and returned \tcode{false}, +returns \tcode{-1}; otherwise \tcode{0}. +\end{itemdescr} + +\rSec3[syncstream.syncbuf.special]{Specialized algorithms} + +\indexlibrarymember{swap}{basic_syncbuf}% +\begin{itemdecl} +template + void swap(basic_syncbuf& a, + basic_syncbuf& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.swap(b)}. +\end{itemdescr} + +\rSec2[syncstream.osyncstream]{Class template \tcode{basic_osyncstream}} + +\rSec3[syncstream.osyncstream.overview]{Overview} + +\indexlibrary{\idxcode{basic_osyncstream}}% +\begin{codeblock} +namespace std { + template + class basic_osyncstream : public basic_ostream { + public: + using char_type = charT; + using int_type = typename traits::int_type; + using pos_type = typename traits::pos_type; + using off_type = typename traits::off_type; + using traits_type = traits; + + using allocator_type = Allocator; + using streambuf_type = basic_streambuf; + using syncbuf_type = basic_syncbuf; + + // \ref{syncstream.osyncstream.cons}, construction and destruction + basic_osyncstream(streambuf_type*, const Allocator&); + explicit basic_osyncstream(streambuf_type* obuf) + : basic_osyncstream(obuf, Allocator()) {} + basic_osyncstream(basic_ostream& os, const Allocator& allocator) + : basic_osyncstream(os.rdbuf(), allocator) {} + explicit basic_osyncstream(basic_ostream& os) + : basic_osyncstream(os, Allocator()) {} + basic_osyncstream(basic_osyncstream&&) noexcept; + ~basic_osyncstream(); + + // \ref{syncstream.osyncstream.assign}, assignment + basic_osyncstream& operator=(basic_osyncstream&&) noexcept; + + // \ref{syncstream.osyncstream.members}, member functions + void emit(); + streambuf_type* get_wrapped() const noexcept; + syncbuf_type* rdbuf() const noexcept { return &sb ; } + + private: + syncbuf_type sb; // \expos + }; +} +\end{codeblock} + +\pnum +\tcode{Allocator} shall meet the allocator requirements\iref{allocator.requirements}. + +\pnum +\begin{example} +A named variable can be used within a block statement for streaming. +\begin{codeblock} +{ + osyncstream bout(cout); + bout << "Hello, "; + bout << "World!"; + bout << endl; // flush is noted + bout << "and more!\n"; +} // characters are transferred and \tcode{cout} is flushed +\end{codeblock} +\end{example} + +\pnum +\begin{example} +A temporary object can be used for streaming within a single statement. +\begin{codeblock} +osyncstream(cout) << "Hello, " << "World!" << '\n'; +\end{codeblock} +In this example, \tcode{cout} is not flushed. +\end{example} + +\rSec3[syncstream.osyncstream.cons]{Construction and destruction} + +\indexlibrary{\idxcode{basic_osyncstream}!constructor}% +\begin{itemdecl} +basic_osyncstream(streambuf_type* buf, const Allocator& allocator); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{sb} from \tcode{buf} and \tcode{allocator}. +Initializes the base class with \tcode{basic_ostream(\&sb)}. + +\pnum +\begin{note} +The member functions of the provided stream buffer +might be called from \tcode{emit()} while a lock is held. +Care should be taken to ensure that this does not result in deadlock. +\end{note} + +\pnum +\postconditions +\tcode{get_wrapped() == buf} is \tcode{true}. +\end{itemdescr} + +\indexlibrary{\idxcode{basic_osyncstream}!constructor}% +\begin{itemdecl} +basic_osyncstream(basic_osyncstream&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Move constructs the base class +and \tcode{sb} from the corresponding subobjects of \tcode{other}, +and calls \tcode{basic_ostream::set_rdbuf(\&sb)}. + +\pnum +\postconditions +The value returned by \tcode{get_wrapped()} +is the value returned by \tcode{os.get_wrapped()} +prior to calling this constructor. +\tcode{nullptr == other.get_wrapped()} is \tcode{true}. +\end{itemdescr} + +\indexlibrary{\idxcode{basic_osyncstream}!destructor}% +\begin{itemdecl} +~basic_osyncstream(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{emit()}. +If an exception is thrown from \tcode{emit()}, +that exception is caught and ignored. +\end{itemdescr} + +\rSec3[syncstream.osyncstream.assign]{Assignment} + +\indexlibrarymember{operator=}{basic_osyncstream}% +\begin{itemdecl} +basic_osyncstream& operator=(basic_osyncstream&& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +First, calls \tcode{emit()}. +If an exception is thrown from \tcode{emit()}, +that exception is caught and ignored. +Move assigns \tcode{sb} from \tcode{rhs.sb}. +\begin{note} +This disassociates \tcode{rhs} +from its wrapped stream buffer +ensuring destruction of \tcode{rhs} produces no output. +\end{note} + +\pnum +\postconditions +\tcode{nullptr == rhs.get_wrapped()} is \tcode{true}. +\tcode{get_wrapped()} returns the value +previously returned by \tcode{rhs.get_wrapped()}. +\end{itemdescr} + +\rSec3[syncstream.osyncstream.members]{Member functions} + +\indexlibrarymember{set_emit_on_sync}{basic_osyncstream}% +\begin{itemdecl} +void emit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{sb.emit()}. +If that call returns \tcode{false}, +calls \tcode{setstate(ios::badbit)}. + +\pnum +\begin{example} +A flush on a \tcode{basic_osyncstream} does not flush immediately: +\begin{codeblock} +{ + osyncstream bout(cout); + bout << "Hello," << '\n'; // no flush + bout.emit(); // characters transferred; \tcode{cout} not flushed + bout << "World!" << endl; // flush noted; \tcode{cout} not flushed + bout.emit(); // characters transferred; \tcode{cout} flushed + bout << "Greetings." << '\n'; // no flush +} // characters transferred; \tcode{cout} not flushed +\end{codeblock} +\end{example} + +\pnum +\begin{example} +The function \tcode{emit()} can be used to +handle exceptions from operations on the underlying stream. +\begin{codeblock} +{ + osyncstream bout(cout); + bout << "Hello, " << "World!" << '\n'; + try { + bout.emit(); + } catch (...) { + // handle exception + } +} +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{set_emit_on_sync}{basic_osyncstream}% +\begin{itemdecl} +streambuf_type* get_wrapped() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{sb.get_wrapped()}. + +\pnum +\begin{example} +Obtaining the wrapped stream buffer with \tcode{get_wrapped()} +allows wrapping it again with an \tcode{osyncstream}. +For example, +\begin{codeblock} +{ + osyncstream bout1(cout); + bout1 << "Hello, "; + { + osyncstream(bout1.get_wrapped()) << "Goodbye, " << "Planet!" << '\n'; + } + bout1 << "World!" << '\n'; +} +\end{codeblock} +produces the \textit{uninterleaved} output +\begin{outputblock} +Goodbye, Planet! +Hello, World! +\end{outputblock} +\end{example} +\end{itemdescr} + \rSec1[filesystems]{File systems} \rSec2[fs.general]{General} @@ -10092,8 +10679,7 @@ subclause are assumed to be qualified with \tcode{::std::filesystem::}. \rSec2[fs.filesystem.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{filesystem}}% -\indexlibrary{\idxhdr{filesystem}}% +\indexhdr{filesystem}% \begin{codeblock} namespace std::filesystem { @@ -10114,17 +10700,17 @@ path operator/ (const path& lhs, const path& rhs); // \ref{fs.path.io}, \tcode{path} inserter and extractor - template + template basic_ostream& operator<<(basic_ostream& os, const path& p); - template + template basic_istream& operator>>(basic_istream& is, path& p); // \ref{fs.path.factory}, \tcode{path} factory functions - template + template path u8path(const Source& source); - template + template path u8path(InputIterator first, InputIterator last); // \ref{fs.class.filesystem_error}, filesystem errors @@ -10398,8 +10984,8 @@ a sequence of elements that identify the location of a file within a filesystem. The elements are the -\grammarterm{root-name}\opt{}, -\grammarterm{root-directory}\opt{}, +\opt{\grammarterm{root-name}}, +\opt{\grammarterm{root-directory}}, and an optional sequence of \grammarterm{filename}{s}\iref{fs.path.generic}. The maximum number of elements in the sequence is operating system dependent\iref{fs.conform.os}. @@ -10450,13 +11036,13 @@ path(const path& p); path(path&& p) noexcept; path(string_type&& source, format fmt = auto_format); - template + template path(const Source& source, format fmt = auto_format); - template + template path(InputIterator first, InputIterator last, format fmt = auto_format); - template + template path(const Source& source, const locale& loc, format fmt = auto_format); - template + template path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); ~path(); @@ -10465,20 +11051,20 @@ path& operator=(path&& p) noexcept; path& operator=(string_type&& source); path& assign(string_type&& source); - template + template path& operator=(const Source& source); - template + template path& assign(const Source& source); - template + template path& assign(InputIterator first, InputIterator last); // \ref{fs.path.append}, appends path& operator/=(const path& p); - template + template path& operator/=(const Source& source); - template + template path& append(const Source& source); - template + template path& append(InputIterator first, InputIterator last); // \ref{fs.path.concat}, concatenation @@ -10487,13 +11073,13 @@ path& operator+=(basic_string_view x); path& operator+=(const value_type* x); path& operator+=(value_type x); - template + template path& operator+=(const Source& x); - template + template path& operator+=(EcharT x); - template + template path& concat(const Source& x); - template + template path& concat(InputIterator first, InputIterator last); // \ref{fs.path.modifiers}, modifiers @@ -10509,8 +11095,8 @@ const value_type* c_str() const noexcept; operator string_type() const; - template , - class Allocator = allocator> + template, + class Allocator = allocator> basic_string string(const Allocator& a = Allocator()) const; std::string string() const; @@ -10520,8 +11106,8 @@ std::u32string u32string() const; // \ref{fs.path.generic.obs}, generic format observers - template , - class Allocator = allocator> + template, + class Allocator = allocator> basic_string generic_string(const Allocator& a = Allocator()) const; std::string generic_string() const; @@ -10547,7 +11133,7 @@ path extension() const; // \ref{fs.path.query}, query - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; bool has_root_path() const; @@ -10601,7 +11187,7 @@ \begin{ncbnf} \nontermdef{pathname}\br - root-name\opt{} root-directory\opt{} relative-path + \opt{root-name} \opt{root-directory} relative-path \end{ncbnf} \begin{ncbnf} @@ -10629,8 +11215,8 @@ \begin{ncbnf} \nontermdef{directory-separator}\br - preferred-separator directory-separator\opt\br - fallback-separator directory-separator\opt + preferred-separator \opt{directory-separator}\br + fallback-separator \opt{directory-separator} \end{ncbnf} \begin{ncbnf} @@ -10734,7 +11320,7 @@ \pnum \begin{note} -The format conversions described in this section +The format conversions described in this subclause are not applied on POSIX-based operating systems because on these systems: \begin{itemize} @@ -10835,7 +11421,7 @@ native narrow encoding is determined by calling a Windows API function. \end{note} \begin{note} -This results in behavior identical to other C and \Cpp +This results in behavior identical to other C and \Cpp{} standard library functions that perform file operations using narrow character strings to identify paths. Changing this behavior would be surprising and error prone. @@ -10958,9 +11544,9 @@ \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} -template +template path(const Source& source, format fmt = auto_format); -template +template path(InputIterator first, InputIterator last, format fmt = auto_format); \end{itemdecl} @@ -10975,9 +11561,9 @@ \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} -template +template path(const Source& source, const locale& loc, format fmt = auto_format); -template +template path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); \end{itemdecl} @@ -11094,11 +11680,11 @@ \indexlibrarymember{operator=}{path}% \indexlibrarymember{assign}{path}% \begin{itemdecl} -template +template path& operator=(const Source& source); -template +template path& assign(const Source& source); -template +template path& assign(InputIterator first, InputIterator last); \end{itemdecl} @@ -11174,9 +11760,9 @@ \indexlibrarymember{operator/=}{path}% \indexlibrarymember{append}{path}% \begin{itemdecl} -template +template path& operator/=(const Source& source); -template +template path& append(const Source& source); \end{itemdecl} @@ -11188,7 +11774,7 @@ \indexlibrarymember{operator/=}{path}% \indexlibrarymember{append}{path}% \begin{itemdecl} -template +template path& append(InputIterator first, InputIterator last); \end{itemdecl} @@ -11207,11 +11793,11 @@ path& operator+=(basic_string_view x); path& operator+=(const value_type* x); path& operator+=(value_type x); -template +template path& operator+=(const Source& x); -template +template path& operator+=(EcharT x); -template +template path& concat(const Source& x); \end{itemdecl} @@ -11229,13 +11815,13 @@ \indexlibrarymember{concat}{path}% \begin{itemdecl} -template +template path& concat(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to \tcode{return *this += path(first, last)}. +\effects Equivalent to: \tcode{return *this += path(first, last);} \end{itemdescr} \rSec4[fs.path.modifiers]{\tcode{path} modifiers} @@ -11396,7 +11982,7 @@ \begin{itemdescr} \pnum -\returns Equivalent to \tcode{native().c_str()}. +\effects Equivalent to: \tcode{return native().c_str();} \end{itemdescr} \indexlibrarymember{operator string_type}{path}% @@ -11416,8 +12002,8 @@ \indexlibrarymember{string}{path}% \begin{itemdecl} -template , - class Allocator = allocator> +template, + class Allocator = allocator> basic_string string(const Allocator& a = Allocator()) const; \end{itemdecl} @@ -11474,8 +12060,8 @@ \indexlibrarymember{generic_string}{path}% \begin{itemdecl} -template , - class Allocator = allocator> +template, + class Allocator = allocator> basic_string generic_string(const Allocator& a = Allocator()) const; \end{itemdecl} @@ -11710,7 +12296,7 @@ \indexlibrarymember{empty}{path}% \begin{itemdecl} -bool empty() const noexcept; +[[nodiscard]] bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -12004,7 +12590,7 @@ \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{lhs.swap(rhs);} +\effects Equivalent to \tcode{lhs.swap(rhs)}. \end{itemdescr} \indexlibrary{\idxcode{hash_value}!\idxcode{path}}% @@ -12109,14 +12695,14 @@ \indexlibrarymember{operator<<}{path}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream& os, const path& p); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to: \tcode{os << quoted(p.string());} +\effects Equivalent to \tcode{os << quoted(p.string())}. \begin{note} The \tcode{quoted} function is described in~\ref{quoted.manip}. \end{note} \pnum @@ -12125,7 +12711,7 @@ \indexlibrarymember{operator>>}{path}% \begin{itemdecl} -template +template basic_istream& operator>>(basic_istream& is, path& p); \end{itemdecl} @@ -12148,9 +12734,9 @@ \indexlibrary{\idxcode{u8path}}% \begin{itemdecl} -template +template path u8path(const Source& source); -template +template path u8path(InputIterator first, InputIterator last); \end{itemdecl} @@ -12334,9 +12920,10 @@ \begin{itemdescr} \pnum \returns A string containing \tcode{runtime_error::what()}. The exact format is unspecified. - Implementations should include \tcode{path1.native_string()} - if not empty, \tcode{path2.native_string()} if not empty, and \tcode{system_error::what()} strings in the returned - string. + Implementations should include + the \tcode{system_error::what()} string and + the pathnames of \tcode{path1} and \tcode{path2} + in the native format in the returned string. \end{itemdescr} \rSec2[fs.enum]{Enumerations} @@ -12588,7 +13175,7 @@ file_status(file_status&&) noexcept = default; ~file_status(); - // assignments: + // assignments file_status& operator=(const file_status&) noexcept = default; file_status& operator=(file_status&&) noexcept = default; @@ -12675,25 +13262,25 @@ directory_entry() noexcept = default; directory_entry(const directory_entry&) = default; directory_entry(directory_entry&&) noexcept = default; - explicit directory_entry(const path& p); - directory_entry(const path& p, error_code& ec); + explicit directory_entry(const filesystem::path& p); + directory_entry(const filesystem::path& p, error_code& ec); ~directory_entry(); - // assignments: + // assignments directory_entry& operator=(const directory_entry&) = default; directory_entry& operator=(directory_entry&&) noexcept = default; // \ref{fs.dir.entry.mods}, modifiers - void assign(const path& p); - void assign(const path& p, error_code& ec); - void replace_filename(const path& p); - void replace_filename(const path& p, error_code& ec); + void assign(const filesystem::path& p); + void assign(const filesystem::path& p, error_code& ec); + void replace_filename(const filesystem::path& p); + void replace_filename(const filesystem::path& p, error_code& ec); void refresh(); void refresh(error_code& ec) noexcept; // \ref{fs.dir.entry.obs}, observers - const path& path() const noexcept; - operator const path&() const noexcept; + const filesystem::path& path() const noexcept; + operator const filesystem::path&() const noexcept; bool exists() const; bool exists(error_code& ec) const noexcept; bool is_block_file() const; @@ -12731,7 +13318,7 @@ bool operator>=(const directory_entry& rhs) const noexcept; private: - path pathobject; // \expos + filesystem::path pathobject; // \expos friend class directory_iterator; // \expos }; } @@ -12796,8 +13383,8 @@ \indexlibrary{\idxcode{directory_entry}!constructor}% \begin{itemdecl} -explicit directory_entry(const path& p); -directory_entry(const path& p, error_code& ec); +explicit directory_entry(const filesystem::path& p); +directory_entry(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -12807,7 +13394,7 @@ \pnum \postconditions \tcode{path() == p} if no error occurs, -otherwise \tcode{path() == std::filesystem::path()}. +otherwise \tcode{path() == filesystem::path()}. \pnum \throws As specified in~\ref{fs.err.report}. @@ -12817,8 +13404,8 @@ \indexlibrarymember{assign}{directory_entry}% \begin{itemdecl} -void assign(const path& p); -void assign(const path& p, error_code& ec); +void assign(const filesystem::path& p); +void assign(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -12833,8 +13420,8 @@ \indexlibrarymember{replace_filename}{directory_entry}% \begin{itemdecl} -void replace_filename(const path& p); -void replace_filename(const path& p, error_code& ec); +void replace_filename(const filesystem::path& p); +void replace_filename(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -12878,10 +13465,10 @@ \tcode{std::filesystem} namespace. \indexlibrarymember{path}{directory_entry}% -\indexlibrarymember{operator const path\&}{directory_entry}% +\indexlibrarymember{operator const filesystem::path\&}{directory_entry}% \begin{itemdecl} -const path& path() const noexcept; -operator const path&() const noexcept; +const filesystem::path& path() const noexcept; +operator const filesystem::path&() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -14073,22 +14660,22 @@ \begin{itemdescr} \pnum -\effects Establishes the postcondition by calling \tcode{create_directory()} for any element of \tcode{p} that does not - exist. +\effects Calls \tcode{create_directory()} for each element of \tcode{p} + that does not exist. \pnum -\postconditions \tcode{is_directory(p)}. - -\pnum -\returns \tcode{true} if a new directory was created, otherwise \tcode{false}. The signature with argument \tcode{ec} returns \tcode{false} if an - error occurs. +\returns \tcode{true} if a new directory was created + for the directory \tcode{p} resolves to, + otherwise \tcode{false}. + The signature with argument \tcode{ec} + returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \complexity \bigoh{n} where \textit{n} is the number of elements - of \tcode{p} that do not exist. + of \tcode{p}. \end{itemdescr} @@ -14102,14 +14689,10 @@ \begin{itemdescr} \pnum -\effects Establishes the postcondition by attempting to create the - directory \tcode{p} resolves to, as if by POSIX \tcode{mkdir()} with a second argument of - \tcode{static_cast(perms::all)}. Creation - failure because \tcode{p} resolves to an existing directory shall not be - treated as an error. - -\pnum -\postconditions \tcode{is_directory(p)}. +\effects Creates the directory \tcode{p} resolves to, + as if by POSIX \tcode{mkdir()} with a second argument of + \tcode{static_cast(perms::all)}. + Creation failure because \tcode{p} already exists is not an error. \pnum \returns \tcode{true} if a new directory was created, otherwise \tcode{false}. @@ -14373,13 +14956,15 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\effects +If \tcode{exists(p)} is \tcode{false}, an error is reported\iref{fs.err.report}. + \pnum \returns \begin{itemize} \item - If \tcode{exists(p)} is \tcode{false}, an error is reported\iref{fs.err.report}. -\item - Otherwise, if \tcode{is_regular_file(p)}, the size in bytes of the file + If \tcode{is_regular_file(p)}, the size in bytes of the file \tcode{p} resolves to, determined as if by the value of the POSIX \tcode{stat} structure member \tcode{st_size} obtained as if by POSIX \tcode{stat()}. \item @@ -15168,8 +15753,14 @@ \begin{itemdescr} \pnum -\returns An unspecified directory path suitable for temporary files. An error shall be reported if -\tcode{exists(p)} is \tcode{false} or \tcode{is_directory(p)} is \tcode{false}, where \tcode{p} is the path to be returned. +Let \tcode{p} be an unspecified directory path suitable for temporary files. + +\pnum +\effects If \tcode{exists(p)} is \tcode{false} or \tcode{is_directory(p)} is + \tcode{false}, an error is reported\iref{fs.err.report}. + +\pnum +\returns The path \tcode{p}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. @@ -15231,8 +15822,7 @@ \rSec1[c.files]{C library files} \rSec2[cstdio.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cstdio}}% -\indextext{\idxhdr{cstdio}}% +\indexhdr{cstdio}% \indexlibrary{\idxcode{size_t}}% \indexlibrary{\idxcode{FILE}}% \indexlibrary{\idxcode{fpos_t}}% @@ -15372,10 +15962,8 @@ \end{codeblock} \pnum -\indextext{\idxhdr{stdio.h}}% -\indexlibrary{\idxhdr{stdio.h}}% -\indextext{\idxhdr{cstdio}}% -\indexlibrary{\idxhdr{cstdio}}% +\indexhdr{stdio.h}% +\indexhdr{cstdio}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}. @@ -15388,8 +15976,7 @@ \rSec2[cinttypes.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cinttypes}}% -\indexlibrary{\idxhdr{cinttypes}}% +\indexhdr{cinttypes}% \indexlibrary{\idxcode{imaxdiv_t}}% \indexlibrary{\idxcode{imaxabs}}% \indexlibrary{\idxcode{imaxdiv}}% @@ -15529,10 +16116,8 @@ \end{codeblock} \pnum -\indextext{\idxhdr{inttypes.h}}% -\indexlibrary{\idxhdr{inttypes.h}}% -\indextext{\idxhdr{cinttypes}}% -\indexlibrary{\idxhdr{cinttypes}}% +\indexhdr{inttypes.h}% +\indexhdr{cinttypes}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}, with the following changes: diff --git a/source/iterators.tex b/source/iterators.tex index 1336f8b90f..dbd9d44930 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4,7 +4,7 @@ \rSec1[iterators.general]{General} \pnum -This Clause describes components that \Cpp programs may use to perform +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}. @@ -32,7 +32,7 @@ \pnum \indextext{requirements!iterator}% -Iterators are a generalization of pointers that allow a \Cpp program to work with different data structures +Iterators are a generalization of pointers that allow a \Cpp{} program to work with different data structures (containers) 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 @@ -67,7 +67,7 @@ \pnum Since iterators are an abstraction of pointers, their semantics is -a generalization of most of the semantics of pointers in \Cpp. +a generalization of most of the semantics of pointers in \Cpp{}. This ensures that every function template that takes iterators @@ -686,14 +686,12 @@ \rSec1[iterator.synopsis]{Header \tcode{}\ synopsis} -\indextext{\idxhdr{iterator}}% -\indexlibrary{\idxhdr{iterator}}% +\indexhdr{iterator}% \begin{codeblock} namespace std { // \ref{iterator.primitives}, primitives template struct iterator_traits; template struct iterator_traits; - template struct iterator_traits; struct input_iterator_tag { }; struct output_iterator_tag { }; @@ -702,162 +700,162 @@ struct random_access_iterator_tag: public bidirectional_iterator_tag { }; // \ref{iterator.operations}, iterator operations - template + template constexpr void advance(InputIterator& i, Distance n); - template + template constexpr typename iterator_traits::difference_type distance(InputIterator first, InputIterator last); - template + template constexpr InputIterator next(InputIterator x, typename iterator_traits::difference_type n = 1); - template + template constexpr BidirectionalIterator prev(BidirectionalIterator x, typename iterator_traits::difference_type n = 1); // \ref{predef.iterators}, predefined iterators - template class reverse_iterator; + template class reverse_iterator; - template + template constexpr bool operator==( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator<( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator!=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator>( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator>=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator<=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr auto operator-( const reverse_iterator& x, const reverse_iterator& y) -> decltype(y.base() - x.base()); - template + template constexpr reverse_iterator operator+( typename reverse_iterator::difference_type n, const reverse_iterator& x); - template + template constexpr reverse_iterator make_reverse_iterator(Iterator i); - template class back_insert_iterator; - template + template class back_insert_iterator; + template back_insert_iterator back_inserter(Container& x); - template class front_insert_iterator; - template + template class front_insert_iterator; + template front_insert_iterator front_inserter(Container& x); - template class insert_iterator; - template + template class insert_iterator; + template insert_iterator inserter(Container& x, typename Container::iterator i); - template class move_iterator; - template + template class move_iterator; + template constexpr bool operator==( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator!=( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator<( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator<=( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator>( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator>=( const move_iterator& x, const move_iterator& y); - template + template constexpr auto operator-( const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); - template + template constexpr move_iterator operator+( typename move_iterator::difference_type n, const move_iterator& x); - template + template constexpr move_iterator make_move_iterator(Iterator i); // \ref{stream.iterators}, stream iterators - template , - class Distance = ptrdiff_t> + template, + class Distance = ptrdiff_t> class istream_iterator; - template + template bool operator==(const istream_iterator& x, const istream_iterator& y); - template + template bool operator!=(const istream_iterator& x, const istream_iterator& y); - template > + template> class ostream_iterator; template> class istreambuf_iterator; - template + template bool operator==(const istreambuf_iterator& a, const istreambuf_iterator& b); - template + template bool operator!=(const istreambuf_iterator& a, const istreambuf_iterator& b); - template > + 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))) + 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))) + 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)); + 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 constexpr auto empty(const C& c) -> decltype(c.empty()); - template constexpr bool empty(const T (&array)[N]) noexcept; - template 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; + 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} @@ -879,6 +877,9 @@ is the type of an iterator, the types +\indexlibrarymember{difference_type}{iterator_traits}% +\indexlibrarymember{value_type}{iterator_traits}% +\indexlibrarymember{iterator_category}{iterator_traits}% \begin{codeblock} iterator_traits::difference_type iterator_traits::value_type @@ -888,6 +889,8 @@ be defined as the iterator's difference type, value type and iterator category, respectively. In addition, the types +\indexlibrarymember{reference}{iterator_traits}% +\indexlibrarymember{pointer}{iterator_traits}% \begin{codeblock} iterator_traits::reference iterator_traits::pointer @@ -929,7 +932,7 @@ namespace std { template struct iterator_traits { using difference_type = ptrdiff_t; - using value_type = T; + using value_type = remove_cv_t; using pointer = T*; using reference = T&; using iterator_category = random_access_iterator_tag; @@ -937,28 +940,14 @@ } \end{codeblock} -and for pointers to const as - -\begin{codeblock} -namespace std { - template struct iterator_traits { - using difference_type = ptrdiff_t; - using value_type = T; - using pointer = const T*; - using reference = const T&; - using iterator_category = random_access_iterator_tag; - }; -} -\end{codeblock} - \pnum \begin{example} To implement a generic \tcode{reverse} -function, a \Cpp program can do the following: +function, a \Cpp{} program can do the following: \begin{codeblock} -template +template void reverse(BidirectionalIterator first, BidirectionalIterator last) { typename iterator_traits::difference_type n = distance(first, last); @@ -1043,24 +1032,24 @@ \begin{example} If \tcode{evolve()} -is well defined for bidirectional iterators, but can be implemented more +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 +template inline void evolve(BidirectionalIterator first, BidirectionalIterator last) { evolve(first, last, typename iterator_traits::iterator_category()); } -template +template void evolve(BidirectionalIterator first, BidirectionalIterator last, bidirectional_iterator_tag) { // more generic, but less efficient algorithm } -template +template void evolve(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag) { // more efficient, but less generic algorithm @@ -1094,7 +1083,7 @@ \indexlibrary{\idxcode{advance}}% \begin{itemdecl} -template +template constexpr void advance(InputIterator& i, Distance n); \end{itemdecl} @@ -1116,7 +1105,7 @@ \indexlibrary{\idxcode{distance}}% \begin{itemdecl} -template +template constexpr typename iterator_traits::difference_type distance(InputIterator first, InputIterator last); \end{itemdecl} @@ -1143,7 +1132,7 @@ \indexlibrary{\idxcode{next}}% \begin{itemdecl} -template +template constexpr InputIterator next(InputIterator x, typename iterator_traits::difference_type n = 1); \end{itemdecl} @@ -1155,7 +1144,7 @@ \indexlibrary{\idxcode{prev}}% \begin{itemdecl} -template +template constexpr BidirectionalIterator prev(BidirectionalIterator x, typename iterator_traits::difference_type n = 1); \end{itemdecl} @@ -1181,7 +1170,7 @@ \indexlibrary{\idxcode{reverse_iterator}}% \begin{codeblock} namespace std { - template + template class reverse_iterator { public: using iterator_type = Iterator; @@ -1193,8 +1182,8 @@ 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); + template constexpr reverse_iterator(const reverse_iterator& u); + template constexpr reverse_iterator& operator=(const reverse_iterator& u); constexpr Iterator base() const; // explicit constexpr reference operator*() const; @@ -1215,40 +1204,40 @@ Iterator current; }; - template + template constexpr bool operator==( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator<( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator!=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator>( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator>=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr bool operator<=( const reverse_iterator& x, const reverse_iterator& y); - template + template constexpr auto operator-( const reverse_iterator& x, const reverse_iterator& y) -> decltype(y.base() - x.base()); - template + template constexpr reverse_iterator operator+( typename reverse_iterator::difference_type n, const reverse_iterator& x); - template + template constexpr reverse_iterator make_reverse_iterator(Iterator i); } \end{codeblock} @@ -1314,7 +1303,7 @@ \indexlibrary{\idxcode{reverse_iterator}!constructor}% \begin{itemdecl} -template constexpr reverse_iterator(const reverse_iterator& u); +template constexpr reverse_iterator(const reverse_iterator& u); \end{itemdecl} \begin{itemdescr} @@ -1330,7 +1319,7 @@ \indexlibrarymember{operator=}{reverse_iterator}% \begin{itemdecl} -template +template constexpr reverse_iterator& operator=(const reverse_iterator& u); \end{itemdecl} @@ -1531,7 +1520,7 @@ \indexlibrarymember{operator==}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator==( const reverse_iterator& x, const reverse_iterator& y); @@ -1547,7 +1536,7 @@ \indexlibrarymember{operator<}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator<( const reverse_iterator& x, const reverse_iterator& y); @@ -1563,7 +1552,7 @@ \indexlibrarymember{operator"!=}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator!=( const reverse_iterator& x, const reverse_iterator& y); @@ -1579,7 +1568,7 @@ \indexlibrarymember{operator>}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator>( const reverse_iterator& x, const reverse_iterator& y); @@ -1595,7 +1584,7 @@ \indexlibrarymember{operator>=}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator>=( const reverse_iterator& x, const reverse_iterator& y); @@ -1611,7 +1600,7 @@ \indexlibrarymember{operator<=}{reverse_iterator}% \begin{itemdecl} -template +template constexpr bool operator<=( const reverse_iterator& x, const reverse_iterator& y); @@ -1627,7 +1616,7 @@ \indexlibrarymember{operator-}{reverse_iterator}% \begin{itemdecl} -template +template constexpr auto operator-( const reverse_iterator& x, const reverse_iterator& y) -> decltype(y.base() - x.base()); @@ -1643,7 +1632,7 @@ \indexlibrarymember{operator+}{reverse_iterator}% \begin{itemdecl} -template +template constexpr reverse_iterator operator+( typename reverse_iterator::difference_type n, const reverse_iterator& x); @@ -1660,7 +1649,7 @@ \indexlibrary{\idxcode{reverse_iterator}!\idxcode{make_reverse_iterator} non-member function}% \indexlibrary{\idxcode{make_reverse_iterator}}% \begin{itemdecl} -template +template constexpr reverse_iterator make_reverse_iterator(Iterator i); \end{itemdecl} @@ -1724,7 +1713,7 @@ \indexlibrary{\idxcode{back_insert_iterator}}% \begin{codeblock} namespace std { - template + template class back_insert_iterator { protected: Container* container; @@ -1746,7 +1735,7 @@ back_insert_iterator operator++(int); }; - template + template back_insert_iterator back_inserter(Container& x); } \end{codeblock} @@ -1831,7 +1820,7 @@ \indexlibrary{\idxcode{back_inserter}}% \begin{itemdecl} -template +template back_insert_iterator back_inserter(Container& x); \end{itemdecl} @@ -1846,7 +1835,7 @@ \indexlibrary{\idxcode{front_insert_iterator}}% \begin{codeblock} namespace std { - template + template class front_insert_iterator { protected: Container* container; @@ -1868,7 +1857,7 @@ front_insert_iterator operator++(int); }; - template + template front_insert_iterator front_inserter(Container& x); } \end{codeblock} @@ -1953,7 +1942,7 @@ \indexlibrary{\idxcode{front_inserter}}% \begin{itemdecl} -template +template front_insert_iterator front_inserter(Container& x); \end{itemdecl} @@ -1968,7 +1957,7 @@ \indexlibrary{\idxcode{insert_iterator}}% \begin{codeblock} namespace std { - template + template class insert_iterator { protected: Container* container; @@ -1991,7 +1980,7 @@ insert_iterator& operator++(int); }; - template + template insert_iterator inserter(Container& x, typename Container::iterator i); } \end{codeblock} @@ -2086,7 +2075,7 @@ \indexlibrary{\idxcode{inserter}}% \begin{itemdecl} -template +template insert_iterator inserter(Container& x, typename Container::iterator i); \end{itemdecl} @@ -2124,7 +2113,7 @@ \indexlibrary{\idxcode{move_iterator}}% \begin{codeblock} namespace std { - template + template class move_iterator { public: using iterator_type = Iterator; @@ -2136,8 +2125,8 @@ 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); + 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; @@ -2158,33 +2147,33 @@ Iterator current; // \expos }; - template + template constexpr bool operator==( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator!=( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator<( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator<=( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator>( const move_iterator& x, const move_iterator& y); - template + template constexpr bool operator>=( const move_iterator& x, const move_iterator& y); - template + template constexpr auto operator-( const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); - template + template constexpr move_iterator operator+( typename move_iterator::difference_type n, const move_iterator& x); - template + template constexpr move_iterator make_move_iterator(Iterator i); } \end{codeblock} @@ -2239,7 +2228,7 @@ \indexlibrary{\idxcode{move_iterator}!constructor}% \begin{itemdecl} -template constexpr move_iterator(const move_iterator& u); +template constexpr move_iterator(const move_iterator& u); \end{itemdecl} \begin{itemdescr} @@ -2256,7 +2245,7 @@ \indexlibrarymember{operator=}{move_iterator}% \begin{itemdecl} -template constexpr move_iterator& operator=(const move_iterator& u); +template constexpr move_iterator& operator=(const move_iterator& u); \end{itemdecl} \begin{itemdescr} @@ -2437,7 +2426,7 @@ \indexlibrarymember{operator==}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator==(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2448,7 +2437,7 @@ \indexlibrarymember{operator"!=}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator!=(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2459,7 +2448,7 @@ \indexlibrarymember{operator<}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator<(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2470,7 +2459,7 @@ \indexlibrarymember{operator<=}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator<=(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2481,7 +2470,7 @@ \indexlibrarymember{operator>}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator>(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2492,7 +2481,7 @@ \indexlibrarymember{operator>=}{move_iterator}% \begin{itemdecl} -template +template constexpr bool operator>=(const move_iterator& x, const move_iterator& y); \end{itemdecl} @@ -2505,7 +2494,7 @@ \indexlibrarymember{operator-}{move_iterator}% \begin{itemdecl} -template +template constexpr auto operator-( const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); @@ -2518,7 +2507,7 @@ \indexlibrarymember{operator+}{move_iterator}% \begin{itemdecl} -template +template constexpr move_iterator operator+( typename move_iterator::difference_type n, const move_iterator& x); \end{itemdecl} @@ -2530,7 +2519,7 @@ \indexlibrary{\idxcode{make_move_iterator}}% \begin{itemdecl} -template +template constexpr move_iterator make_move_iterator(Iterator i); \end{itemdecl} @@ -2612,8 +2601,8 @@ \begin{codeblock} namespace std { - template , - class Distance = ptrdiff_t> + template, + class Distance = ptrdiff_t> class istream_iterator { public: using iterator_category = input_iterator_tag; @@ -2640,10 +2629,10 @@ T value; // \expos }; - template + template bool operator==(const istream_iterator& x, const istream_iterator& y); - template + template bool operator!=(const istream_iterator& x, const istream_iterator& y); } @@ -2778,7 +2767,7 @@ \indexlibrarymember{operator==}{istream_iterator}% \begin{itemdecl} -template +template bool operator==(const istream_iterator& x, const istream_iterator& y); \end{itemdecl} @@ -2791,7 +2780,7 @@ \indexlibrarymember{operator"!=}{istream_iterator}% \begin{itemdecl} -template +template bool operator!=(const istream_iterator& x, const istream_iterator& y); \end{itemdecl} @@ -2831,7 +2820,7 @@ \begin{codeblock} namespace std { - template > + template> class ostream_iterator { public: using iterator_category = output_iterator_tag; @@ -3026,10 +3015,10 @@ streambuf_type* sbuf_; // \expos }; - template + template bool operator==(const istreambuf_iterator& a, const istreambuf_iterator& b); - template + template bool operator!=(const istreambuf_iterator& a, const istreambuf_iterator& b); } @@ -3040,7 +3029,7 @@ \indexlibrary{\idxcode{proxy}!\idxcode{istreambuf_iterator}}% \begin{codeblock} namespace std { - template > + template> class istreambuf_iterator::proxy { // \expos charT keep_; basic_streambuf* sbuf_; @@ -3069,7 +3058,7 @@ \rSec3[istreambuf.iterator.cons]{\tcode{istreambuf_iterator} constructors} \pnum -For each \tcode{istreambuf_iterator} constructor in this section, +For each \tcode{istreambuf_iterator} constructor in this subclause, an end-of-stream iterator is constructed if and only if the exposition-only member \tcode{sbuf_} is initialized with a null pointer value. @@ -3180,7 +3169,7 @@ \indexlibrarymember{operator==}{istreambuf_iterator}% \begin{itemdecl} -template +template bool operator==(const istreambuf_iterator& a, const istreambuf_iterator& b); \end{itemdecl} @@ -3193,7 +3182,7 @@ \indexlibrarymember{operator"!=}{istreambuf_iterator}% \begin{itemdecl} -template +template bool operator!=(const istreambuf_iterator& a, const istreambuf_iterator& b); \end{itemdecl} @@ -3209,7 +3198,7 @@ \indexlibrary{\idxcode{ostreambuf_iterator}}% \begin{codeblock} namespace std { - template > + template> class ostreambuf_iterator { public: using iterator_category = output_iterator_tag; @@ -3359,8 +3348,8 @@ \indexlibrary{\idxcode{begin(C\&)}}% \begin{itemdecl} -template constexpr auto begin(C& c) -> decltype(c.begin()); -template constexpr auto begin(const C& c) -> decltype(c.begin()); +template constexpr auto begin(C& c) -> decltype(c.begin()); +template constexpr auto begin(const C& c) -> decltype(c.begin()); \end{itemdecl} \begin{itemdescr} @@ -3370,8 +3359,8 @@ \indexlibrary{\idxcode{end(C\&)}}% \begin{itemdecl} -template constexpr auto end(C& c) -> decltype(c.end()); -template constexpr auto end(const C& c) -> decltype(c.end()); +template constexpr auto end(C& c) -> decltype(c.end()); +template constexpr auto end(const C& c) -> decltype(c.end()); \end{itemdecl} \begin{itemdescr} @@ -3381,7 +3370,7 @@ \indexlibrary{\idxcode{begin(T (\&)[N])}}% \begin{itemdecl} -template constexpr T* begin(T (&array)[N]) noexcept; +template constexpr T* begin(T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3391,7 +3380,7 @@ \indexlibrary{\idxcode{end(T (\&)[N])}}% \begin{itemdecl} -template constexpr T* end(T (&array)[N]) noexcept; +template constexpr T* end(T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3401,7 +3390,7 @@ \indexlibrary{\idxcode{cbegin(const C\&)}}% \begin{itemdecl} -template constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) +template constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c)); \end{itemdecl} \begin{itemdescr} @@ -3410,7 +3399,7 @@ \indexlibrary{\idxcode{cend(const C\&)}}% \begin{itemdecl} -template constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) +template constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); \end{itemdecl} \begin{itemdescr} @@ -3419,8 +3408,8 @@ \indexlibrary{\idxcode{rbegin(C\&)}}% \begin{itemdecl} -template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); -template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); +template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); +template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{c.rbegin()}. @@ -3428,8 +3417,8 @@ \indexlibrary{\idxcode{rend(C\&)}}% \begin{itemdecl} -template constexpr auto rend(C& c) -> decltype(c.rend()); -template constexpr auto rend(const C& c) -> decltype(c.rend()); +template constexpr auto rend(C& c) -> decltype(c.rend()); +template constexpr auto rend(const C& c) -> decltype(c.rend()); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{c.rend()}. @@ -3437,7 +3426,7 @@ \indexlibrary{\idxcode{rbegin(T (\&array)[N])}}% \begin{itemdecl} -template constexpr reverse_iterator rbegin(T (&array)[N]); +template constexpr reverse_iterator rbegin(T (&array)[N]); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{reverse_iterator(array + N)}. @@ -3445,7 +3434,7 @@ \indexlibrary{\idxcode{rend(T (\&array)[N])}}% \begin{itemdecl} -template constexpr reverse_iterator rend(T (&array)[N]); +template constexpr reverse_iterator rend(T (&array)[N]); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{reverse_iterator(array)}. @@ -3453,7 +3442,7 @@ \indexlibrary{\idxcode{rbegin(initializer_list)}}% \begin{itemdecl} -template constexpr reverse_iterator rbegin(initializer_list il); +template constexpr reverse_iterator rbegin(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{reverse_iterator(il.end())}. @@ -3461,7 +3450,7 @@ \indexlibrary{\idxcode{rend(initializer_list)}}% \begin{itemdecl} -template constexpr reverse_iterator rend(initializer_list il); +template constexpr reverse_iterator rend(initializer_list il); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{reverse_iterator(il.begin())}. @@ -3469,7 +3458,7 @@ \indexlibrary{\idxcode{crbegin(const C\& c)}}% \begin{itemdecl} -template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); +template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{std::rbegin(c)}. @@ -3477,7 +3466,7 @@ \indexlibrary{\idxcode{crend(const C\& c)}}% \begin{itemdecl} -template constexpr auto crend(const C& c) -> decltype(std::rend(c)); +template constexpr auto crend(const C& c) -> decltype(std::rend(c)); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{std::rend(c)}. @@ -3495,7 +3484,7 @@ \indexlibrary{\idxcode{size(C\& c)}}% \begin{itemdecl} -template constexpr auto size(const C& c) -> decltype(c.size()); +template constexpr auto size(const C& c) -> decltype(c.size()); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{c.size()}. @@ -3503,7 +3492,7 @@ \indexlibrary{\idxcode{size(T (\&array)[N])}}% \begin{itemdecl} -template constexpr size_t size(const T (&array)[N]) noexcept; +template constexpr size_t size(const T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{N}. @@ -3511,7 +3500,7 @@ \indexlibrary{\idxcode{empty(C\& c)}}% \begin{itemdecl} -template constexpr auto empty(const C& c) -> decltype(c.empty()); +template [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty()); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{c.empty()}. @@ -3519,7 +3508,7 @@ \indexlibrary{\idxcode{empty(T (\&array)[N])}}% \begin{itemdecl} -template constexpr bool empty(const T (&array)[N]) noexcept; +template [[nodiscard]] constexpr bool empty(const T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{false}. @@ -3527,7 +3516,7 @@ \indexlibrary{\idxcode{empty(initializer_list)}}% \begin{itemdecl} -template constexpr bool empty(initializer_list il) noexcept; +template [[nodiscard]] constexpr bool empty(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{il.size() == 0}. @@ -3535,8 +3524,8 @@ \indexlibrary{\idxcode{data(C\& c)}}% \begin{itemdecl} -template constexpr auto data(C& c) -> decltype(c.data()); -template constexpr auto data(const C& c) -> decltype(c.data()); +template constexpr auto data(C& c) -> decltype(c.data()); +template constexpr auto data(const C& c) -> decltype(c.data()); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{c.data()}. @@ -3544,7 +3533,7 @@ \indexlibrary{\idxcode{data(T (\&array)[N])}}% \begin{itemdecl} -template constexpr T* data(T (&array)[N]) noexcept; +template constexpr T* data(T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{array}. @@ -3552,7 +3541,7 @@ \indexlibrary{\idxcode{data(initializer_list)}}% \begin{itemdecl} -template constexpr const E* data(initializer_list il) noexcept; +template constexpr const E* data(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{il.begin()}. diff --git a/source/lex.tex b/source/lex.tex index 0d852ef93b..12e8e80da5 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -35,7 +35,7 @@ directive \tcode{\#include}, less any source lines skipped by any of the conditional inclusion\iref{cpp.cond} preprocessing directives, is called a \defn{translation unit}. -\begin{note} A \Cpp program need not all be translated at the same time. +\begin{note} A \Cpp{} program need not all be translated at the same time. \end{note} \pnum @@ -302,7 +302,7 @@ of characters that matches the raw-string pattern \begin{ncbnf} -encoding-prefix\opt{} \terminal{R} raw-string +\opt{encoding-prefix} \terminal{R} raw-string \end{ncbnf} \item Otherwise, if the next three characters are \tcode{<::} and the subsequent character @@ -555,9 +555,9 @@ forming valid external identifiers. For example, some otherwise unused character or sequence of characters may be used to encode the \tcode{\textbackslash u} in a \grammarterm{universal-character-name}. Extended -characters may produce a long external identifier, but \Cpp does not +characters may produce a long external identifier, but \Cpp{} does not place a translation limit on significant characters for external -identifiers. In \Cpp, upper- and lower-case letters are considered +identifiers. In \Cpp{}, upper- and lower-case letters are considered different for all identifiers, including external identifiers. } \begin{floattable}{Ranges of characters allowed}{tab:charname.allowed} @@ -639,7 +639,7 @@ \indextext{\idxcode{_}|see{character, underscore}}% \indextext{character!underscore!in identifier}% \indextext{reserved identifier}% -In addition, some identifiers are reserved for use by \Cpp +In addition, some identifiers are reserved for use by \Cpp{} implementations and shall not be used otherwise; no diagnostic is required. \begin{itemize} @@ -788,7 +788,7 @@ \pnum \indextext{operator|(}% \indextext{punctuator|(}% -The lexical representation of \Cpp programs includes a number of +The lexical representation of \Cpp{} programs includes a number of preprocessing tokens which are used in the syntax of the preprocessor or are converted into tokens for operators and punctuators: @@ -796,13 +796,13 @@ \nontermdef{preprocessing-op-or-punc} \textnormal{one of}\br \>\{ \>\} \>[ \>] \>\# \>\#\# \>( \>)\br \><: \>:> \><\% \>\%> \>\%: \>\%:\%: \>; \>: \>.{..}\br -\>new \>delete \>? \>:: \>. \>.*\br -\>+ \>- \>* \>/ \>\% \>\caret \>\& \>| \>\tilde\br -\>! \>= \>< \>> \>+= \>-= \>*= \>/= \>\%=\br -\>\caret= \>\&= \>|= \><< \>>> \>>>= \><<= \>== \>!=\br -\><= \>>= \>\&\& \>|| \>++ \>-{-} \>, \>->* \>->\br -\>and \>and_eq \>bitand \>bitor \>compl \>not \>not_eq\br -\>or \>or_eq \>xor \>xor_eq +\>new \>delete \>? \>:: \>. \>.* \>-> \>->* \>\~\br +\>! \>+ \>- \>* \>/ \>\% \>\caret \>\& \>|\br +\>= \>+= \>-= \>*= \>/= \>\%= \>\caret= \>\&= \>|=\br +\>== \>!= \>< \>> \><= \>>= \><=> \>\&\& \>||\br +\><< \>>> \><<= \>>>= \>++ \>-{-} \>,\br +\>and \>or \>xor \>not \>bitand \>bitor \>compl\br +\>and_eq \>or_eq \>xor_eq \>not_eq \end{bnfkeywordtab} Each \grammarterm{preprocessing-op-or-punc} is converted to a single token @@ -838,29 +838,29 @@ \indextext{literal!integer}% \begin{bnf} \nontermdef{integer-literal}\br - binary-literal integer-suffix\opt\br - octal-literal integer-suffix\opt\br - decimal-literal integer-suffix\opt\br - hexadecimal-literal integer-suffix\opt + binary-literal \opt{integer-suffix}\br + octal-literal \opt{integer-suffix}\br + decimal-literal \opt{integer-suffix}\br + hexadecimal-literal \opt{integer-suffix} \end{bnf} \begin{bnf} \nontermdef{binary-literal}\br \terminal{0b} binary-digit\br \terminal{0B} binary-digit\br - binary-literal \terminal{'}\opt binary-digit + binary-literal \opt{\terminal{'}} binary-digit \end{bnf} \begin{bnf} \nontermdef{octal-literal}\br \terminal{0}\br - octal-literal \terminal{'}\opt octal-digit + octal-literal \opt{\terminal{'}} octal-digit \end{bnf} \begin{bnf} \nontermdef{decimal-literal}\br nonzero-digit\br - decimal-literal \terminal{'}\opt digit + decimal-literal \opt{\terminal{'}} digit \end{bnf} \begin{bnf} @@ -892,7 +892,7 @@ \begin{bnf} \nontermdef{hexadecimal-digit-sequence}\br hexadecimal-digit\br - hexadecimal-digit-sequence \terminal{'}\opt hexadecimal-digit + hexadecimal-digit-sequence \opt{\terminal{'}} hexadecimal-digit \end{bnf} \begin{bnf} @@ -904,10 +904,10 @@ \begin{bnf} \nontermdef{integer-suffix}\br - unsigned-suffix long-suffix\opt \br - unsigned-suffix long-long-suffix\opt \br - long-suffix unsigned-suffix\opt \br - long-long-suffix unsigned-suffix\opt + unsigned-suffix \opt{long-suffix} \br + unsigned-suffix \opt{long-long-suffix} \br + long-suffix \opt{unsigned-suffix} \br + long-long-suffix \opt{unsigned-suffix} \end{bnf} \begin{bnf} @@ -1051,7 +1051,7 @@ \indextext{literal!character}% \begin{bnf} \nontermdef{character-literal}\br - encoding-prefix\opt{} \terminal{'} c-char-sequence \terminal{'} + \opt{encoding-prefix} \terminal{'} c-char-sequence \terminal{'} \end{bnf} \begin{bnf} @@ -1156,10 +1156,10 @@ \indextext{prefix!\idxcode{u}}% is a character literal of type \tcode{char16_t}. The value of a \tcode{char16_t} character literal containing a single \grammarterm{c-char} is -equal to its ISO 10646 code point value, provided that the code point is -representable with a single 16-bit code unit. (That is, provided it is a -basic multi-lingual plane code point.) If the value is not representable -within 16 bits, the program is ill-formed. A \tcode{char16_t} character literal +equal to its ISO 10646 code point value, provided that the code point value is +representable with a single 16-bit code unit (that is, provided it is in the +basic multi-lingual plane). If the value is not representable +with a single 16-bit code unit, the program is ill-formed. A \tcode{char16_t} character literal containing multiple \grammarterm{c-char}{s} is ill-formed. \pnum @@ -1177,7 +1177,7 @@ \pnum \indextext{literal!character!wide}% \indextext{wide-character}% -\indextext{\idxhdr{stddef.h}}% +\indexhdr{stddef.h}% \indextext{type!\idxcode{wchar_t}}% A character literal that begins with the letter \tcode{L}, such as \tcode{L'z'}, @@ -1199,7 +1199,7 @@ \pnum Certain non-graphic characters, the single quote \tcode{'}, the double quote \tcode{"}, the question mark \tcode{?},\footnote{Using an escape sequence for a question mark -is supported for compatibility with ISO \CppXIV and ISO C.} +is supported for compatibility with ISO \CppXIV{} and ISO C.} and the backslash \indextext{backslash character}% \indextext{\idxcode{\textbackslash}|see{backslash character}}% @@ -1285,38 +1285,38 @@ \begin{bnf} \nontermdef{decimal-floating-literal}\br - fractional-constant exponent-part\opt floating-suffix\opt\br - digit-sequence exponent-part floating-suffix\opt + fractional-constant \opt{exponent-part} \opt{floating-suffix}\br + digit-sequence exponent-part \opt{floating-suffix} \end{bnf} \begin{bnf} \nontermdef{hexadecimal-floating-literal}\br - hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffix\opt\br - hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffix\opt + hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part \opt{floating-suffix}\br + hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part \opt{floating-suffix} \end{bnf} \begin{bnf} \nontermdef{fractional-constant}\br - digit-sequence\opt{} \terminal{.} digit-sequence\br + \opt{digit-sequence} \terminal{.} digit-sequence\br digit-sequence \terminal{.} \end{bnf} \begin{bnf} \nontermdef{hexadecimal-fractional-constant}\br - hexadecimal-digit-sequence\opt{} \terminal{.} hexadecimal-digit-sequence\br + \opt{hexadecimal-digit-sequence} \terminal{.} hexadecimal-digit-sequence\br hexadecimal-digit-sequence \terminal{.} \end{bnf} \begin{bnf} \nontermdef{exponent-part}\br - \terminal{e} sign\opt digit-sequence\br - \terminal{E} sign\opt digit-sequence + \terminal{e} \opt{sign} digit-sequence\br + \terminal{E} \opt{sign} digit-sequence \end{bnf} \begin{bnf} \nontermdef{binary-exponent-part}\br - \terminal{p} sign\opt digit-sequence\br - \terminal{P} sign\opt digit-sequence + \terminal{p} \opt{sign} digit-sequence\br + \terminal{P} \opt{sign} digit-sequence \end{bnf} \begin{bnf} @@ -1327,7 +1327,7 @@ \begin{bnf} \nontermdef{digit-sequence}\br digit\br - digit-sequence \terminal{'}\opt digit + digit-sequence \opt{\terminal{'}} digit \end{bnf} \begin{bnf} @@ -1398,8 +1398,8 @@ \indextext{literal!string}% \begin{bnf} \nontermdef{string-literal}\br - encoding-prefix\opt{} \terminal{"} s-char-sequence\opt{} \terminal{"}\br - encoding-prefix\opt{} \terminal{R} raw-string + \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br + \opt{encoding-prefix} \terminal{R} raw-string \end{bnf} \begin{bnf} @@ -1418,7 +1418,7 @@ \begin{bnf} \nontermdef{raw-string}\br - \terminal{"} d-char-sequence\opt{} \terminal{(} r-char-sequence\opt{} \terminal{)} d-char-sequence\opt{} \terminal{"} + \terminal{"} \opt{d-char-sequence} \terminal{(} \opt{r-char-sequence} \terminal{)} \opt{d-char-sequence} \terminal{"} \end{bnf} \begin{bnf} @@ -1581,7 +1581,7 @@ A \grammarterm{string-literal} that begins with \tcode{L}, \indextext{prefix!\idxcode{L}}% such as \tcode{L"asdf"}, is a \defn{wide string literal}. -\indextext{\idxhdr{stddef.h}}% +\indexhdr{stddef.h}% \indextext{type!\idxcode{wchar_t}}% \indextext{literal!string!wide}% \indextext{prefix!\idxcode{L}}% @@ -1712,8 +1712,8 @@ The pointer literal is the keyword \tcode{nullptr}. It is a prvalue of type \tcode{std::nullptr_t}. \begin{note} -\tcode{std::nullptr_t} is a distinct type that is neither a pointer type nor a pointer -to member type; rather, a prvalue of this type is a null pointer constant and can be +\tcode{std::nullptr_t} is a distinct type that is neither a pointer type nor a pointer-to-member type; +rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See~\ref{conv.ptr} and~\ref{conv.mem}. \end{note} @@ -1739,7 +1739,7 @@ \begin{bnf} \nontermdef{user-defined-floating-literal}\br - fractional-constant exponent-part\opt ud-suffix\br + fractional-constant \opt{exponent-part} ud-suffix\br digit-sequence exponent-part ud-suffix\br hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix\br hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 669f2e2990..71bd00d2df 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -5,9 +5,9 @@ \pnum This Clause describes the contents of the -\term{\Cpp standard library}, +\term{\Cpp{} standard library}, \indextext{library!C++ standard}% -how a well-formed \Cpp program makes use of the library, and +how a well-formed \Cpp{} program makes use of the library, and how a conforming implementation may provide the entities in the library. \pnum @@ -16,7 +16,7 @@ library. \ref{requirements}, \ref{\firstlibchapter} through \ref{\lastlibchapter}, and \ref{depr} specify the contents of the library, as well as library requirements and constraints on both well-formed -\Cpp programs and conforming implementations. +\Cpp{} programs and conforming implementations. \pnum Detailed specifications for each of the components in the library are in @@ -41,19 +41,19 @@ \pnum The language support library\iref{language.support} provides components that are -required by certain parts of the \Cpp language, such as memory allocation~(\ref{expr.new}, +required by certain parts of the \Cpp{} language, such as memory allocation~(\ref{expr.new}, \ref{expr.delete}) and exception processing\iref{except}. \pnum The diagnostics library\iref{diagnostics} provides a consistent framework for -reporting errors in a \Cpp program, including predefined exception classes. +reporting errors in a \Cpp{} program, including predefined exception classes. \pnum The general utilities library\iref{utilities} includes components used by other library elements, such as a predefined storage allocator for dynamic storage management\iref{basic.stc.dynamic}, and components used as infrastructure -in \Cpp programs, +in \Cpp{} programs, such as tuples, function wrappers, and time facilities. \pnum @@ -74,7 +74,7 @@ \pnum The containers\iref{containers}, iterators\iref{iterators}, -and algorithms\iref{algorithms} libraries provide a \Cpp program with access +and algorithms\iref{algorithms} libraries provide a \Cpp{} program with access to a subset of the most widely used algorithms and data structures. \pnum @@ -91,7 +91,7 @@ \pnum The input/output library\iref{input.output} provides the \tcode{iostream} -components that are the primary mechanism for \Cpp program input and output. +components that are the primary mechanism for \Cpp{} program input and output. They can be used with other elements of the library, particularly strings, locales, and iterators. @@ -109,7 +109,7 @@ \rSec1[library.c]{The C standard library} \pnum -The \Cpp standard library also makes available the facilities of the C standard library, +The \Cpp{} standard library also makes available the facilities of the C standard library, \indextext{library!C standard}% suitably adjusted to ensure static type safety. @@ -168,7 +168,6 @@ \begin{defnote} It is used for one of the template parameters of the string, iostream, and regular expression class templates. -A character container type is a POD\iref{basic.types} type. \end{defnote} \definition{comparison function}{defns.comparison} @@ -228,10 +227,10 @@ \definition{handler function}{defns.handler} \indexdefn{function!handler}% \term{non-reserved function} -whose definition may be provided by a \Cpp program +whose definition may be provided by a \Cpp{} program \begin{defnote} -A \Cpp program may designate a handler function at various points in its execution by +A \Cpp{} program may designate a handler function at various points in its execution by supplying a pointer to the function when calling any of the library functions that install handler functions\iref{language.support}. \end{defnote} @@ -293,7 +292,7 @@ \definition{referenceable type}{defns.referenceable} \indexdefn{type!referenceable}% type that is either an -an object type, a function type that does not have cv-qualifiers or a +object type, a function type that does not have cv-qualifiers or a \grammarterm{ref-qualifier}, or a reference type \begin{defnote} @@ -304,7 +303,7 @@ \definition{replacement function}{defns.replacement} \indexdefn{function!replacement}% non-reserved function -whose definition is provided by a \Cpp program +whose definition is provided by a \Cpp{} program \begin{defnote} Only one definition for such a function is in effect for the duration of the program's @@ -328,18 +327,18 @@ the behavior of any such function definition in the program \begin{defnote} -If such a function defined in a \Cpp program fails to meet the required +If such a function defined in a \Cpp{} program fails to meet the required behavior when it executes, the behavior is undefined.% \indextext{undefined} \end{defnote} \definition{reserved function}{defns.reserved.function} \indexdefn{function!reserved}% -function, specified as part of the \Cpp standard library, that is defined by the +function, specified as part of the \Cpp{} standard library, that is defined by the implementation \begin{defnote} -If a \Cpp program provides a definition for any reserved function, the results are undefined.% +If a \Cpp{} program provides a definition for any reserved function, the results are undefined.% \indextext{undefined} \end{defnote} @@ -373,7 +372,7 @@ \rSec1[description]{Method of description (Informative)} \pnum -This subclause describes the conventions used to specify the \Cpp standard +This subclause describes the conventions used to specify the \Cpp{} standard library. \ref{structure} describes the structure of the normative \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr}. \ref{conventions} describes other editorial conventions. @@ -402,10 +401,6 @@ Each subclause also provides a summary, listing the headers specified in the subclause and the library entities provided in each header. -\pnum -Paragraphs labeled ``Note(s):'' or ``Example(s):'' are informative, other paragraphs -are normative. - \pnum The contents of the summary and the detailed specifications include: @@ -422,7 +417,7 @@ \pnum \indextext{requirements}% -Requirements describe constraints that shall be met by a \Cpp program that extends the standard library. +Requirements describe constraints that shall be met by a \Cpp{} program that extends the standard library. Such extensions are generally one of the following: \begin{itemize} @@ -455,7 +450,7 @@ See~\ref{type.descriptions}. \pnum -In some cases the semantic requirements are presented as \Cpp code. +In some cases the semantic requirements are presented as \Cpp{} code. Such code is intended as a specification of equivalence of a construct to another construct, not necessarily as the way the construct @@ -510,18 +505,18 @@ \end{itemize} \pnum -Whenever the \effects element specifies that the semantics of some function +Whenever the \Fundescx{Effects} element specifies that the semantics of some function \tcode{F} are \techterm{Equivalent to} some code sequence, then the various elements are -interpreted as follows. If \tcode{F}'s semantics specifies a \requires element, then +interpreted as follows. If \tcode{F}'s semantics specifies a \Fundescx{Requires} element, then that requirement is logically imposed prior to the \techterm{equivalent-to} semantics. -Next, the semantics of the code sequence are determined by the \requires, \effects, -\sync, \postconditions, \returns, \throws, \complexity, \remarks, and \errors +Next, the semantics of the code sequence are determined by the \Fundescx{Requires}, \Fundescx{Effects}, +\Fundescx{Synchronization}, \Fundescx{Postconditions}, \Fundescx{Returns}, \Fundescx{Throws}, \Fundescx{Complexity}, \Fundescx{Remarks}, and \Fundescx{Error conditions} specified for the function invocations contained in the code sequence. The value -returned from \tcode{F} is specified by \tcode{F}'s \returns element, or if \tcode{F} -has no \returns element, a non-\tcode{void} return from \tcode{F} is specified by the +returned from \tcode{F} is specified by \tcode{F}'s \Fundescx{Returns} element, or if \tcode{F} +has no \Fundescx{Returns} element, a non-\tcode{void} return from \tcode{F} is specified by the \tcode{return} statements in the code sequence. -If \tcode{F}'s semantics contains a \throws, -\postconditions, or \complexity element, then that supersedes any occurrences of that +If \tcode{F}'s semantics contains a \Fundescx{Throws}, +\Fundescx{Postconditions}, or \Fundescx{Complexity} element, then that supersedes any occurrences of that element in the code sequence. \pnum @@ -532,7 +527,7 @@ describes a function definition provided by the implementation. The \defnx{required behavior}{behavior!required} describes the semantics of a function definition provided by -either the implementation or a \Cpp program. +either the implementation or a \Cpp{} program. Where no distinction is explicitly made in the description, the behavior described is the required behavior. @@ -554,7 +549,7 @@ \rSec3[structure.see.also]{C library} \pnum -Paragraphs labeled ``\xref'' contain cross-references to the relevant portions +Paragraphs labeled ``\textsc{See also}'' contain cross-references to the relevant portions of the ISO C standard. \rSec2[conventions]{Other conventions} @@ -562,7 +557,7 @@ \pnum This subclause describes several editorial conventions used to describe the contents -of the \Cpp standard library. +of the \Cpp{} standard library. These conventions are for describing implementation-defined types\iref{type.descriptions}, and member functions\iref{functions.within.classes}. @@ -583,7 +578,7 @@ \tcode{ForwardIterator}.} These names are used in library Clauses to describe the types that -may be supplied as arguments by a \Cpp program when instantiating template components from +may be supplied as arguments by a \Cpp{} program when instantiating template components from the library. \pnum @@ -762,8 +757,8 @@ \tcode{}\iref{c.locales}. \indextext{\idxcode{setlocale}}% \indexlibrary{\idxcode{setlocale}}% -\indextext{\idxhdr{clocale}}% -\indexlibrary{\idxhdr{clocale}}} +\indexhdr{clocale}% +\indexhdr{clocale}} or by a change to a \tcode{locale} object, as described in \ref{locales} and \ref{input.output}. @@ -794,35 +789,33 @@ A \indextext{NTBS}% \defnx{null-terminated byte string}{string!null-terminated byte}, -or \ntbs, +or \ntbs{}, is a character sequence whose highest-addressed element with defined content has the value zero (the \term{terminating null} character); no other element in the sequence has the value zero.% -\indextext{\idxhdr{cstring}}% -\indexlibrary{\idxhdr{cstring}}% +\indexhdr{cstring}% \indextext{NTBS}\footnote{Many of the objects manipulated by function signatures declared in \tcode{}\iref{c.strings} are character sequences or \ntbs{}s. -\indextext{\idxhdr{cstring}}% -\indexlibrary{\idxhdr{cstring}}% +\indexhdr{cstring}% The size of some of these character sequences is limited by a length value, maintained separately from the character sequence.} \pnum The -\term{length} of an \ntbs +\term{length} of an \ntbs{} is the number of elements that precede the terminating null character. \indextext{NTBS}% An -\term{empty} \ntbs +\term{empty} \ntbs{} has a length of zero. \pnum The -\term{value} of an \ntbs +\term{value} of an \ntbs{} is the sequence of values of the elements up to and including the terminating null character. \indextext{NTBS}% @@ -830,11 +823,11 @@ \pnum A \indextext{NTBS}% -\defnx{static}{NTBS!static} \ntbs -is an \ntbs with +\defnx{static}{NTBS!static} \ntbs{} +is an \ntbs{} with static storage duration.\footnote{A string literal, such as \tcode{"abc"}, -is a static \ntbs.} +is a static \ntbs{}.} \rSec5[multibyte.strings]{Multibyte strings} @@ -842,17 +835,18 @@ \indextext{NTBS}% \indextext{NTMBS}% A \defnx{null-terminated multibyte string}{string!null-terminated multibyte}, -or \ntmbs, is an \ntbs that constitutes a +or \ntmbs{}, +is an \ntbs{} that constitutes a sequence of valid multibyte characters, beginning and ending in the initial -shift state.\footnote{An \ntbs that contains characters only from the -basic execution character set is also an \ntmbs. +shift state.\footnote{An \ntbs{} that contains characters only from the +basic execution character set is also an \ntmbs{}. Each multibyte character then consists of a single byte.} \pnum A -\defnx{static}{NTMBS!static} \ntmbs -is an \ntmbs with static storage duration. +\defnx{static}{NTMBS!static} \ntmbs{} +is an \ntmbs{} with static storage duration. \indextext{NTMBS}% \rSec3[functions.within.classes]{Functions within classes} @@ -876,6 +870,75 @@ \begin{note} This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution. \end{note} +\rSec3[operators]{Operators} + +\pnum +In this library, whenever a declaration is provided for an \tcode{operator!=}, +\tcode{operator>}, \tcode{operator>=}, or \tcode{operator<=} +for a type \tcode{T}, +its requirements and semantics are as follows, +unless explicitly specified otherwise. + +\indexlibrary{\idxcode{operator"!=}}% +\begin{itemdecl} +bool operator!=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). + +\pnum +\returns +\tcode{!(x == y)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>}}% +\begin{itemdecl} +bool operator>(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{y < x}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}}% +\begin{itemdecl} +bool operator<=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}}% +\begin{itemdecl} +bool operator>=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\returns +\tcode{!(x < y)}. +\end{itemdescr} + \rSec3[objects.within.classes]{Private members} \pnum @@ -903,7 +966,7 @@ \rSec1[requirements]{Library-wide requirements} \pnum -This subclause specifies requirements that apply to the entire \Cpp standard library. +This subclause specifies requirements that apply to the entire \Cpp{} standard library. \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} specify the requirements of individual entities within the library. @@ -913,27 +976,27 @@ \pnum Within this subclause, \ref{organization} describes the library's contents and -organization, \ref{using} describes how well-formed \Cpp programs gain access to library +organization, \ref{using} describes how well-formed \Cpp{} programs gain access to library entities, \ref{utility.requirements} describes constraints on types and functions used with -the \Cpp standard library, -\ref{constraints} describes constraints on well-formed \Cpp programs, and +the \Cpp{} standard library, +\ref{constraints} describes constraints on well-formed \Cpp{} programs, and \ref{conforming} describes constraints on conforming implementations. \rSec2[organization]{Library contents and organization} \pnum -\ref{contents} describes the entities and macros defined in the \Cpp standard library. +\ref{contents} describes the entities and macros defined in the \Cpp{} standard library. \ref{headers} lists the standard library headers and some constraints on those headers. -\ref{compliance} lists requirements for a freestanding implementation of the \Cpp +\ref{compliance} lists requirements for a freestanding implementation of the \Cpp{} standard library. \rSec3[contents]{Library contents} \pnum -The \Cpp standard library provides definitions +The \Cpp{} standard library provides definitions for the entities and macros described in the synopses -of the \Cpp standard library headers\iref{headers}. +of the \Cpp{} standard library headers\iref{headers}. \pnum All library entities except @@ -944,7 +1007,7 @@ \tcode{std} or namespaces nested within namespace \tcode{std}.\footnote{The C standard library headers\iref{depr.c.headers} also define -names within the global namespace, while the \Cpp headers for C library +names within the global namespace, while the \Cpp{} headers for C library facilities\iref{headers} may also define names within the global namespace.}% \indextext{namespace} It is unspecified whether names declared in a specific namespace are declared @@ -956,7 +1019,7 @@ Whenever a name \tcode{x} defined in the standard library is mentioned, the name \tcode{x} is assumed to be fully qualified as \tcode{::std::x}, -unless explicitly described otherwise. For example, if the \effects section +unless explicitly described otherwise. For example, if the \effects element for library function \tcode{F} is described as calling library function \tcode{G}, the function \tcode{::std::G} @@ -965,98 +1028,98 @@ \rSec3[headers]{Headers} \pnum -Each element of the \Cpp standard library is declared or defined (as appropriate) in a +Each element of the \Cpp{} standard library is declared or defined (as appropriate) in a \term{header}.\footnote{A header is not necessarily a source file, nor are the sequences delimited by \tcode{<} and \tcode{>} in header names necessarily valid source file names\iref{cpp.include}.} \pnum -The \Cpp standard library provides the -\defnx{\Cpp library headers}{header!C++ library}, +The \Cpp{} standard library provides the +\defnx{\Cpp{} library headers}{header!C++ library}, shown in Table~\ref{tab:cpp.library.headers}. -\begin{floattable}{\Cpp library headers}{tab:cpp.library.headers} +\begin{floattable}{\Cpp{} library headers}{tab:cpp.library.headers} {llll} \topline \tcode{} & +\tcode{} & +\tcode{} & +\tcode{} \\ + +\tcode{} & \tcode{} & \tcode{} & \tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & \tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ -\tcode{} & +\tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\tcode{} \\ +\tcode{} \\ \tcode{} & \tcode{} & \tcode{} & -\\ - -\tcode{} & -\tcode{} & -\tcode{} & -\\ +\tcode{} \\ \end{floattable} @@ -1064,16 +1127,16 @@ The facilities of the C standard library are provided in the \indextext{library!C standard}% additional headers shown in Table~\ref{tab:cpp.c.headers}.% -\footnote{It is intentional that there is no \Cpp header +\footnote{It is intentional that there is no \Cpp{} header for any of these C headers: -\indextext{\idxhdr{stdatomic.h}}% -\indextext{\idxhdr{stdnoreturn.h}}% -\indextext{\idxhdr{threads.h}}% +\indexhdr{stdatomic.h}% +\indexhdr{stdnoreturn.h}% +\indexhdr{threads.h}% \tcode{}, \tcode{}, \tcode{}.} -\begin{floattable}{\Cpp headers for C library facilities}{tab:cpp.c.headers} +\begin{floattable}{\Cpp{} headers for C library facilities}{tab:cpp.c.headers} {lllll} \topline @@ -1117,7 +1180,7 @@ and \ref{depr}, the contents of each header \tcode{c\placeholder{name}} is the same as that of the corresponding header \tcode{\placeholder{name}.h} as specified in the C standard library\iref{intro.refs}. -In the \Cpp standard library, however, the +In the \Cpp{} standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope\iref{basic.scope.namespace} of the namespace \tcode{std}. It is unspecified whether these names (including any overloads added in @@ -1127,7 +1190,7 @@ \grammarterm{using-declaration}{s}\iref{namespace.udecl}. \pnum -Names which are defined as macros in C shall be defined as macros in the \Cpp +Names which are defined as macros in C shall be defined as macros in the \Cpp{} standard library, even if C grants license for implementation as functions. \begin{note} The names defined as macros in C include the following: \tcode{assert}, \tcode{offsetof}, \tcode{setjmp}, \tcode{va_arg}, @@ -1135,22 +1198,22 @@ \pnum Names that are defined as functions in C shall be defined as functions in the -\Cpp standard library.\footnote{This disallows the practice, allowed in C, of +\Cpp{} standard library.\footnote{This disallows the practice, allowed in C, of providing a masking macro in addition to the function prototype. The only way to -achieve equivalent inline behavior in \Cpp is to provide a definition as an +achieve equivalent inline behavior in \Cpp{} is to provide a definition as an extern inline function.} \pnum -Identifiers that are keywords or operators in \Cpp shall not be defined as -macros in \Cpp standard library headers.\footnote{In particular, including the +Identifiers that are keywords or operators in \Cpp{} shall not be defined as +macros in \Cpp{} standard library headers.\footnote{In particular, including the standard header \tcode{} or \tcode{} has no effect.} \pnum \ref{depr.c.headers}, C standard library headers, describes the effects of using -the \tcode{\placeholder{name}.h} (C header) form in a \Cpp program.\footnote{ The +the \tcode{\placeholder{name}.h} (C header) form in a \Cpp{} program.\footnote{ The \tcode{".h"} headers dump all their names into the global namespace, whereas the newer forms keep their names in namespace \tcode{std}. Therefore, the newer -forms are the preferred forms for all uses except for \Cpp programs which are +forms are the preferred forms for all uses except for \Cpp{} programs which are intended to be strictly compatible with C. } \pnum @@ -1163,9 +1226,9 @@ as the C library function with the unsuffixed name, but generally take an additional argument whose value is the size of the result array. -If any \Cpp header is included, +If any \Cpp{} header is included, it is \impldef{whether functions from Annex K of the C standard library -are declared when \Cpp headers are included} +are declared when \Cpp{} headers are included} whether any of these names is declared in the global namespace. (None of them is declared in namespace \tcode{std}.) @@ -1287,7 +1350,7 @@ \impldef{headers for freestanding implementation} set of headers. This set shall include at least the headers shown in Table~\ref{tab:cpp.headers.freestanding}. -\begin{libsumtab}{\Cpp headers for freestanding implementations}{tab:cpp.headers.freestanding} +\begin{libsumtab}{\Cpp{} headers for freestanding implementations}{tab:cpp.headers.freestanding} & & \tcode{} \\ \rowsep \ref{support.types} & Types & \tcode{} \\ \rowsep \ref{support.limits} & Implementation properties & \tcode{} \tcode{} \tcode{} \\ \rowsep @@ -1306,8 +1369,7 @@ \pnum The supplied version of the header \tcode{} -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% shall declare at least the functions \indexlibrary{\idxcode{abort}}% \tcode{abort}, @@ -1327,15 +1389,15 @@ \rSec3[using.overview]{Overview} \pnum -This section describes how a \Cpp program gains access to the facilities of the -\Cpp standard library. \ref{using.headers} describes effects during translation +Subclause \ref{using} describes how a \Cpp{} program gains access to the facilities of the +\Cpp{} standard library. \ref{using.headers} describes effects during translation phase 4, while~\ref{using.linkage} describes effects during phase 8\iref{lex.phases}. \rSec3[using.headers]{Headers} \pnum -The entities in the \Cpp standard library are defined in headers, +The entities in the \Cpp{} standard library are defined in headers, whose contents are made available to a translation unit when it contains the appropriate \indextext{unit!translation}% \tcode{\#include} @@ -1352,10 +1414,8 @@ or \tcode{} depends each time on the lexically -\indextext{\idxhdr{cassert}}% -\indexlibrary{\idxhdr{cassert}}% -\indextext{\idxhdr{assert.h}}% -\indexlibrary{\idxhdr{assert.h}}% +\indexhdr{cassert}% +\indexhdr{assert.h}% current definition of \indextext{\idxcode{NDEBUG}}% \indexlibrary{\idxcode{NDEBUG}}% @@ -1371,7 +1431,7 @@ \rSec3[using.linkage]{Linkage} \pnum -Entities in the \Cpp standard library have external linkage\iref{basic.link}. +Entities in the \Cpp{} standard library have external linkage\iref{basic.link}. Unless otherwise specified, objects and functions have the default \tcode{extern "C++"} linkage\iref{dcl.link}. @@ -1397,7 +1457,7 @@ \pnum Objects and functions -defined in the library and required by a \Cpp program are included in +defined in the library and required by a \Cpp{} program are included in the program prior to program startup. \indextext{startup!program}% @@ -1411,7 +1471,7 @@ \pnum \ref{utility.arg.requirements} describes requirements on types and expressions used to instantiate templates -defined in the \Cpp standard library. +defined in the \Cpp{} standard library. \ref{swappable.requirements} describes the requirements on swappable types and swappable expressions. \ref{nullablepointer.requirements} describes the requirements on pointer-like @@ -1423,11 +1483,11 @@ \rSec3[utility.arg.requirements]{Template argument requirements} \pnum -The template definitions in the \Cpp standard library +The template definitions in the \Cpp{} standard library refer to various named requirements whose details are set out in Tables~\ref{tab:equalitycomparable}--\ref{tab:destructible}. In these tables, \tcode{T} is an object or reference type to be -supplied by a \Cpp program instantiating a template; +supplied by a \Cpp{} program instantiating a template; \tcode{a}, \tcode{b}, and \tcode{c} are values of type (possibly \tcode{const}) \tcode{T}; @@ -1602,7 +1662,7 @@ #include // Requires: \tcode{std::forward(t)} shall be swappable with \tcode{std::forward(u)}. -template +template void value_swap(T&& t, U&& u) { using std::swap; swap(std::forward(t), std::forward(u)); // OK: uses ``swappable with'' conditions @@ -1610,11 +1670,11 @@ } // Requires: lvalues of \tcode{T} shall be swappable. -template +template void lv_swap(T& t1, T& t2) { using std::swap; - swap(t1, t2); // OK: uses swappable conditions for -} // lvalues of type \tcode{T} + swap(t1, t2); // OK: uses swappable conditions for lvalues of type \tcode{T} +} namespace N { struct A { int m; }; @@ -1812,6 +1872,8 @@ by calling \tcode{a1.allocate}, where \tcode{a1 == a} \\ \rowsep \tcode{q} & a value of type \tcode{XX::const_pointer} obtained by conversion from a value \tcode{p}. \\ \rowsep +\tcode{r} & a value of type \tcode{T\&} +obtained by the expression \tcode{*p}. \\ \rowsep \tcode{w} & a value of type \tcode{XX::void_pointer} obtained by conversion from a value \tcode{p} \\ \rowsep \tcode{x} & a value of type \tcode{XX::const_void_pointer} obtained by @@ -1900,7 +1962,7 @@ \tcode{pointer_traits<\brk{}X::pointer\brk{}>::pointer_to(r)} & \tcode{X::pointer} & - & \\ \rowsep + same as \tcode{p} & \\ \rowsep \tcode{a.allocate(n)} & \tcode{X::pointer} & Memory is allocated for \tcode{n} objects of type \tcode{T} but objects @@ -2107,20 +2169,20 @@ Table~\ref{tab:utilities.allocator.requirements}: \begin{codeblock} -template +template struct SimpleAllocator { typedef Tp value_type; SimpleAllocator(@\textit{ctor args}@); - template SimpleAllocator(const SimpleAllocator& other); + template SimpleAllocator(const SimpleAllocator& other); - Tp* allocate(std::size_t n); + [[nodiscard]] Tp* allocate(std::size_t n); void deallocate(Tp* p, std::size_t n); }; -template +template bool operator==(const SimpleAllocator&, const SimpleAllocator&); -template +template bool operator!=(const SimpleAllocator&, const SimpleAllocator&); \end{codeblock} \end{example} @@ -2151,8 +2213,8 @@ \rSec3[constraints.overview]{Overview} \pnum -This section describes restrictions on \Cpp programs that use the facilities of -the \Cpp standard library. The following subclauses specify constraints on the +Subclause \ref{constraints} describes restrictions on \Cpp{} programs that use the facilities of +the \Cpp{} standard library. The following subclauses specify constraints on the program's use of namespaces\iref{namespace.std}, its use of various reserved names\iref{reserved.names}, its use of headers\iref{alt.headers}, its use of standard library classes as base classes\iref{derived.classes}, its @@ -2164,7 +2226,7 @@ \rSec4[namespace.std]{Namespace \tcode{std}} \pnum -The behavior of a \Cpp program is undefined if it adds declarations or definitions to namespace +The behavior of a \Cpp{} program is undefined if it adds declarations or definitions to namespace \tcode{std} or to a namespace within namespace \tcode{std} @@ -2180,13 +2242,13 @@ that meets the minimum requirements of this document.} \pnum -The behavior of a \Cpp program is undefined +The behavior of a \Cpp{} program is undefined if it declares an explicit or partial specialization of any standard library variable template, except where explicitly permitted by the specification of that variable template. \pnum -The behavior of a \Cpp program is undefined if it declares +The behavior of a \Cpp{} program is undefined if it declares \begin{itemize} \item an explicit specialization of any member function of a standard library class template, or @@ -2210,7 +2272,7 @@ \rSec4[namespace.posix]{Namespace \tcode{posix}} \pnum -The behavior of a \Cpp program is undefined if it adds declarations or definitions to namespace +The behavior of a \Cpp{} program is undefined if it adds declarations or definitions to namespace \tcode{posix} or to a namespace within namespace \tcode{posix} @@ -2223,7 +2285,7 @@ Top level namespaces with a name starting with \tcode{std} and followed by a non-empty sequence of digits are reserved for future standardization. -The behavior of a \Cpp program is undefined if +The behavior of a \Cpp{} program is undefined if it adds declarations or definitions to such a namespace. \begin{example} The top level namespace \tcode{std2} is reserved for use by future revisions of this International Standard. \end{example} @@ -2232,7 +2294,7 @@ \indextext{name!reserved} \pnum -The \Cpp standard library reserves the following kinds of names: +The \Cpp{} standard library reserves the following kinds of names: \begin{itemize} \item macros \item global names @@ -2307,8 +2369,7 @@ \indextext{linkage!external}\footnote{The list of such reserved names includes \tcode{errno}, declared or defined in -\indextext{\idxhdr{cerrno}}% -\indexlibrary{\idxhdr{cerrno}}% +\indexhdr{cerrno}% \tcode{}.} both in namespace \tcode{std} @@ -2327,16 +2388,14 @@ \indexlibrary{\idxcode{setjmp}}% \tcode{setjmp(jmp_buf)}, declared or defined in -\indextext{\idxhdr{csetjmp}}% -\indexlibrary{\idxhdr{csetjmp}}% +\indexhdr{csetjmp}% \tcode{}, and \indexlibrary{\idxcode{va_end}}% \indexlibrary{\idxcode{va_list}}% \tcode{va_end(va_list)}, declared or defined in -\indextext{\idxhdr{cstdarg}}% -\indexlibrary{\idxhdr{cstdarg}}% +\indexhdr{cstdarg}% \tcode{}.} \pnum @@ -2362,12 +2421,9 @@ \tcode{extern "C++"} linkage,\footnote{The function signatures declared in \indextext{Amendment 1}% -\indextext{\idxhdr{cuchar}}% -\indexlibrary{\idxhdr{cuchar}}% -\indextext{\idxhdr{cwchar}}% -\indexlibrary{\idxhdr{cwchar}}% -\indextext{\idxhdr{cwctype}}% -\indexlibrary{\idxhdr{cwctype}}% +\indexhdr{cuchar}% +\indexhdr{cwchar}% +\indexhdr{cwctype}% \tcode{}, \tcode{}, and @@ -2415,7 +2471,7 @@ \pnum If a file with a name -equivalent to the derived file name for one of the \Cpp standard library headers +equivalent to the derived file name for one of the \Cpp{} standard library headers is not provided as part of the implementation, and a file with that name is placed in any of the standard places for a source file to be included\iref{cpp.include}, the behavior is undefined.% @@ -2427,7 +2483,7 @@ \pnum Virtual member function signatures defined \indextext{function!virtual member}% -for a base class in the \Cpp standard +for a base class in the \Cpp{} standard \indextext{class!base}% \indextext{library!C++ standard}% library may be overridden in a derived class defined in the program\iref{class.virtual}. @@ -2438,14 +2494,14 @@ \indextext{definition!alternate}% \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} describe the behavior of numerous functions defined by -the \Cpp standard library. +the \Cpp{} standard library. Under some circumstances, \indextext{library!C++ standard}% however, certain of these function descriptions also apply to replacement functions defined in the program\iref{definitions}. \pnum -A \Cpp program may provide the definition for any of the following +A \Cpp{} program may provide the definition for any of the following dynamic memory allocation function signatures declared in header \tcode{}~(\ref{basic.stc.dynamic}, \ref{support.dynamic}): @@ -2498,7 +2554,7 @@ \rSec3[handler.functions]{Handler functions} \pnum -The \Cpp standard library provides a default version of the following handler +The \Cpp{} standard library provides a default version of the following handler function\iref{language.support}: \begin{itemize} @@ -2508,7 +2564,7 @@ \end{itemize} \pnum -A \Cpp program may install different handler functions during execution, by +A \Cpp{} program may install different handler functions during execution, by supplying a pointer to a function defined in the program or the library as an argument to (respectively): \begin{itemize} @@ -2519,7 +2575,7 @@ Exception handling. \pnum -A \Cpp program can get a pointer to the current handler function by calling the following +A \Cpp{} program can get a pointer to the current handler function by calling the following functions: \begin{itemize} @@ -2540,8 +2596,8 @@ \pnum In certain cases (replacement functions, handler functions, operations on types used to -instantiate standard library template components), the \Cpp standard library depends on -components supplied by a \Cpp program. +instantiate standard library template components), the \Cpp{} standard library depends on +components supplied by a \Cpp{} program. If these components do not meet their requirements, this document places no requirements on the implementation. @@ -2586,7 +2642,7 @@ \indextext{argument}% Each of the following applies to all arguments \indextext{argument}% -to functions defined in the \Cpp standard library,% +to functions defined in the \Cpp{} standard library,% \indextext{library!C++ standard} unless explicitly stated otherwise. @@ -2611,13 +2667,17 @@ \begin{note} If the parameter is a generic parameter of the form \tcode{T\&\&} and an lvalue of type \tcode{A} is bound, the argument binds to an lvalue reference\iref{temp.deduct.call} -and thus is not covered by the previous sentence. \end{note} \begin{note} If a program casts -an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function -with the argument \tcode{std::move(x)}), the program +and thus is not covered by the previous sentence. +\end{note} +\begin{note} +If a program casts +an lvalue to an xvalue while passing that lvalue to a library function +(e.g., by calling the function with the argument \tcode{std::move(x)}), the program is effectively asking that function to treat that lvalue as a temporary object. The implementation is free to optimize away aliasing checks which might be needed if the argument was -an lvalue. \end{note} +an lvalue. +\end{note} \end{itemize} \rSec3[res.on.objects]{Library object access} @@ -2654,7 +2714,7 @@ \rSec3[conforming.overview]{Overview} \pnum -This section describes the constraints upon, and latitude of, implementations of the \Cpp standard library. +Subclause \ref{conforming} describes the constraints upon, and latitude of, implementations of the \Cpp{} standard library. \pnum An implementation's use of headers is discussed in~\ref{res.on.headers}, its use @@ -2667,9 +2727,9 @@ \rSec3[res.on.headers]{Headers} \pnum -A \Cpp header may include other \Cpp headers. -A \Cpp header shall provide the declarations and definitions that appear in its -synopsis. A \Cpp header shown in its synopsis as including other \Cpp headers +A \Cpp{} header may include other \Cpp{} headers. +A \Cpp{} header shall provide the declarations and definitions that appear in its +synopsis. A \Cpp{} header shown in its synopsis as including other \Cpp{} headers shall provide the declarations and definitions that appear in the synopses of those other headers. @@ -2680,7 +2740,7 @@ \pnum The C standard library headers\iref{depr.c.headers} -shall include only their corresponding \Cpp standard library header, +shall include only their corresponding \Cpp{} standard library header, as described in~\ref{headers}. \rSec3[res.on.macro.definitions]{Restrictions on macro definitions} @@ -2706,17 +2766,17 @@ \pnum It is unspecified whether any non-member -functions in the \Cpp standard library are defined as -\tcode{inline}\iref{dcl.inline}. +functions in the \Cpp{} standard library are defined as +inline\iref{dcl.inline}. \pnum A call to a non-member function signature described in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} shall behave as if the implementation declared no additional -non-member function signatures.\footnote{A valid \Cpp program always +non-member function signatures.\footnote{A valid \Cpp{} program always calls the expected library non-member function. An implementation may also define additional non-member functions that would otherwise not -be called by a valid \Cpp program.} +be called by a valid \Cpp{} program.} \pnum An implementation shall not declare a non-member function signature @@ -2746,11 +2806,11 @@ \rSec3[member.functions]{Member functions} \pnum -It is unspecified whether any member functions in the \Cpp standard library are defined as -\tcode{inline}\iref{dcl.inline}. +It is unspecified whether any member functions in the \Cpp{} standard library are defined as +inline\iref{dcl.inline}. \pnum -For a non-virtual member function described in the \Cpp standard library, +For a non-virtual member function described in the \Cpp{} standard library, an implementation may declare a different set of member function signatures, provided that any call to the member function that would select an overload from the set of declarations described in this document @@ -2797,25 +2857,25 @@ \pnum Except where explicitly specified in this document, it is \impldef{which functions in -the \Cpp standard library may be recursively reentered} which functions in the \Cpp standard +the \Cpp{} standard library may be recursively reentered} which functions in the \Cpp{} standard library may be recursively reentered. \rSec3[res.on.data.races]{Data race avoidance} \pnum -This section specifies requirements that implementations shall meet to prevent data +This subclause specifies requirements that implementations shall meet to prevent data races\iref{intro.multithread}. Every standard library function shall meet each requirement unless otherwise specified. Implementations may prevent data races in cases other than those specified below. \pnum -A \Cpp standard library function shall not directly or indirectly access +A \Cpp{} standard library function shall not directly or indirectly access objects\iref{intro.multithread} accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including \tcode{this}. \pnum -A \Cpp standard library function shall not directly or indirectly modify +A \Cpp{} standard library function shall not directly or indirectly modify objects\iref{intro.multithread} accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's non-const arguments, including \tcode{this}. @@ -2826,7 +2886,7 @@ programs that do not explicitly share objects between threads. \end{note} \pnum -A \Cpp standard library function shall not access objects indirectly accessible via its +A \Cpp{} standard library function shall not access objects indirectly accessible via its arguments or via elements of its container arguments except by invoking functions required by its specification on those container elements. @@ -2841,7 +2901,7 @@ not visible to users and are protected against data races. \pnum -Unless otherwise specified, \Cpp standard library functions shall perform all operations +Unless otherwise specified, \Cpp{} standard library functions shall perform all operations solely within the current thread if those operations have effects that are visible\iref{intro.multithread} to users. @@ -2856,8 +2916,7 @@ \indextext{protection}% It is unspecified whether any function signature or class described in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} is a -\tcode{friend} -of another class in the \Cpp standard library. +friend of another class in the \Cpp{} standard library. \indextext{specifier!\idxcode{friend}} \rSec3[derivation]{Derived classes} @@ -2865,13 +2924,13 @@ \pnum \indextext{class!derived}% \indextext{class!base}% -An implementation may derive any class in the \Cpp standard library from a class with a +An implementation may derive any class in the \Cpp{} standard library from a class with a name reserved to the implementation. \pnum -Certain classes defined in the \Cpp standard library are required to be derived from +Certain classes defined in the \Cpp{} standard library are required to be derived from other classes -in the \Cpp standard library. +in the \Cpp{} standard library. \indextext{library!C++ standard}% An implementation may derive such a class directly from the required base or indirectly through a hierarchy of base classes with names reserved to the implementation. @@ -2897,7 +2956,7 @@ \end{itemize} \pnum -All types specified in the \Cpp standard library shall be non-\tcode{final} types +All types specified in the \Cpp{} standard library shall be non-\tcode{final} types unless otherwise specified. \rSec3[res.on.exception.handling]{Restrictions on exception handling}% @@ -2905,7 +2964,7 @@ \indextext{exception handling!handler} \pnum -Any of the functions defined in the \Cpp standard library +Any of the functions defined in the \Cpp{} standard library \indextext{library!C++ standard}% can report a failure by throwing an exception of a type described in its \throws @@ -2931,14 +2990,14 @@ \tcode{bsearch()}\iref{alg.c.library} meet this condition.} \pnum -Destructor operations defined in the \Cpp standard library +Destructor operations defined in the \Cpp{} standard library shall not throw exceptions. -Every destructor in the \Cpp standard library shall behave as if it had a +Every destructor in the \Cpp{} standard library shall behave as if it had a non-throwing exception specification. \pnum Functions defined in the -\Cpp standard library +\Cpp{} standard library \indextext{specifications!C++}% that do not have a \throws @@ -2979,7 +3038,7 @@ \rSec3[value.error.codes]{Value of error codes} \pnum -Certain functions in the \Cpp standard library report errors via a +Certain functions in the \Cpp{} standard library report errors via a \tcode{std::error_code}\iref{syserr.errcode.overview} object. That object's \tcode{category()} member shall return \tcode{std::system_category()} for errors originating from the operating system, or a reference to an @@ -2997,7 +3056,7 @@ \rSec3[lib.types.movedfrom]{Moved-from state of library types} \pnum -Objects of types defined in the \Cpp standard library may be moved +Objects of types defined in the \Cpp{} standard library may be moved from\iref{class.copy}. Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state. diff --git a/source/limits.tex b/source/limits.tex index 37d35bd06d..0bf337993e 100644 --- a/source/limits.tex +++ b/source/limits.tex @@ -2,7 +2,7 @@ \infannex{implimits}{Implementation quantities} \pnum -Because computers are finite, \Cpp implementations are inevitably +Because computers are finite, \Cpp{} implementations are inevitably limited in the size of the programs they can successfully process. Every implementation shall document those limitations where known. @@ -19,114 +19,114 @@ However, these quantities are only guidelines and do not determine compliance. \begin{itemize} \item% -Nesting levels of compound statements, -iteration control structures, -and selection control structures [256]. +Nesting levels of compound statements\iref{stmt.block}, +iteration control structures\iref{stmt.iter}, +and selection control structures\iref{stmt.select} [256]. \item% -Nesting levels of conditional inclusion [256]. +Nesting levels of conditional inclusion\iref{cpp.cond} [256]. \item% -Pointer, array, and function declarators +Pointer\iref{dcl.ptr}, array\iref{dcl.array}, and function\iref{dcl.fct} declarators (in any combination) modifying a class, arithmetic, or incomplete type in a declaration [256]. \item% -Nesting levels of parenthesized expressions within a full-expression [256]. +Nesting levels of parenthesized expressions\iref{expr.prim.paren} within a full-expression [256]. \item% Number of -characters in an internal identifier -or macro name [1\,024]. +characters in an internal identifier\iref{lex.name} +or macro name\iref{cpp.replace} [1\,024]. \item% Number of -characters in an external identifier [1\,024]. +characters in an external identifier (\ref{lex.name}, \ref{basic.link}) [1\,024]. \item% -External identifiers in one translation unit [65\,536]. +External identifiers\iref{basic.link} in one translation unit [65\,536]. \item% -Identifiers with block scope declared in one block [1\,024]. +Identifiers with block scope declared in one block\iref{basic.scope.block} [1\,024]. \item% -Structured bindings introduced in one declaration [256]. +Structured bindings\iref{dcl.struct.bind} introduced in one declaration [256]. \item% -Macro identifiers simultaneously defined in one +Macro identifiers\iref{cpp.replace} simultaneously defined in one translation unit [65\,536]. \item% -Parameters in one function definition [256]. +Parameters in one function definition\iref{dcl.fct.def.general} [256]. \item% -Arguments in one function call [256]. +Arguments in one function call\iref{expr.call} [256]. \item% -Parameters in one macro definition [256]. +Parameters in one macro definition\iref{cpp.replace} [256]. \item% -Arguments in one macro invocation [256]. +Arguments in one macro invocation\iref{cpp.replace} [256]. \item% -Characters in one logical source line [65\,536]. +Characters in one logical source line\iref{lex.phases} [65\,536]. \item% -Characters in a string literal -(after concatenation) [65\,536]. +Characters in a string literal\iref{lex.string} +(after concatenation\iref{lex.phases}) [65\,536]. \item% -Size of an object [262\,144]. +Size of an object\iref{intro.object} [262\,144]. \item% Nesting levels for \tcode{\#include} -files [256]. +files\iref{cpp.include} [256]. \item% Case labels for a \tcode{switch} -statement (excluding those for any nested +statement\iref{stmt.switch} (excluding those for any nested \tcode{switch} statements) [16\,384]. \item% -Data members in a single class [16\,384]. +Data members in a single class\iref{class.mem} [16\,384]. \item% -Lambda-captures in one \grammarterm{lambda-expression} [256]. +Lambda-captures in one \grammarterm{lambda-expression}\iref{expr.prim.lambda.capture} [256]. \item% -Enumeration constants in a single enumeration [4\,096]. +Enumeration constants in a single enumeration\iref{dcl.enum} [4\,096]. \item% -Levels of nested class definitions +Levels of nested class definitions\iref{class.nest} in a single \grammarterm{member-specification} [256]. \item% Functions registered by -\tcode{atexit()} [32]. +\tcode{atexit()}\iref{support.start.term} [32]. \item% Functions registered by -\tcode{at_quick_exit()} [32]. +\tcode{at_quick_exit()}\iref{support.start.term} [32]. \item% -Direct and indirect base classes [16\,384]. +Direct and indirect base classes\iref{class.derived} [16\,384]. \item% -Direct base classes for a single class [1\,024]. +Direct base classes for a single class\iref{class.derived} [1\,024]. \item% -Members declared in a single class [4\,096]. +Members declared in a single class\iref{class.mem} [4\,096]. \item% Final overriding virtual functions in a class, -accessible or not [16\,384]. +accessible or not\iref{class.virtual} [16\,384]. \item% -Direct and indirect virtual bases of a class [1\,024]. +Direct and indirect virtual bases of a class\iref{class.mi} [1\,024]. \item% -Static members of a class [1\,024]. +Static members of a class\iref{class.static} [1\,024]. \item% -Friend declarations in a class [4\,096]. +Friend declarations in a class\iref{class.friend} [4\,096]. \item% -Access control declarations in a class [4\,096]. +Access control declarations in a class\iref{class.access.spec} [4\,096]. \item% -Member initializers in a constructor definition [6\,144]. +Member initializers in a constructor definition\iref{class.base.init} [6\,144]. \item% -\grammarterm{initializer-clause}{s} in one \grammarterm{braced-init-list} [16\,384]. +\grammarterm{initializer-clause}{s} in one \grammarterm{braced-init-list}\iref{dcl.init} [16\,384]. \item% -Scope qualifications of one identifier [256]. +Scope qualifications of one identifier\iref{expr.prim.id.qual} [256]. \item% Nested external specifications [1\,024]. \item% -Recursive constexpr function invocations [512]. +Recursive constexpr function invocations\iref{dcl.constexpr} [512]. \item% -Full-expressions evaluated within a core constant expression [1\,048\,576]. +Full-expressions evaluated within a core constant expression\iref{expr.const} [1\,048\,576]. \item% -Template arguments in a template declaration [1\,024]. +Template arguments in a template declaration\iref{temp.param} [1\,024]. \item% -Recursively nested template instantiations, including substitution +Recursively nested template instantiations\iref{temp.inst}, including substitution during template argument deduction\iref{temp.deduct} [1\,024]. \item% -Handlers per try block [256]. +Handlers per try block\iref{except.handle} [256]. \item% Number of placeholders\iref{func.bind.place} [10]. diff --git a/source/locales.tex b/source/locales.tex index 0070fcd7e7..6de8b6398a 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -4,7 +4,7 @@ \rSec1[localization.general]{General} \pnum -This Clause describes components that \Cpp programs may use to +This Clause describes components that \Cpp{} programs may use to encapsulate (and therefore be more portable when confronting) cultural differences. The locale facility includes internationalization @@ -24,80 +24,79 @@ \rSec1[locale.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{locale}}% -\indexlibrary{\idxhdr{locale}}% +\indexhdr{locale}% \begin{codeblock} namespace std { // \ref{locale}, locale class locale; - template const Facet& use_facet(const locale&); - template bool has_facet(const locale&) noexcept; + template const Facet& use_facet(const locale&); + template bool has_facet(const locale&) noexcept; // \ref{locale.convenience}, convenience interfaces - template bool isspace (charT c, const locale& loc); - template bool isprint (charT c, const locale& loc); - template bool iscntrl (charT c, const locale& loc); - template bool isupper (charT c, const locale& loc); - template bool islower (charT c, const locale& loc); - template bool isalpha (charT c, const locale& loc); - template bool isdigit (charT c, const locale& loc); - template bool ispunct (charT c, const locale& loc); - template bool isxdigit(charT c, const locale& loc); - template bool isalnum (charT c, const locale& loc); - template bool isgraph (charT c, const locale& loc); - template bool isblank (charT c, const locale& loc); - template charT toupper(charT c, const locale& loc); - template charT tolower(charT c, const locale& loc); + template bool isspace (charT c, const locale& loc); + template bool isprint (charT c, const locale& loc); + template bool iscntrl (charT c, const locale& loc); + template bool isupper (charT c, const locale& loc); + template bool islower (charT c, const locale& loc); + template bool isalpha (charT c, const locale& loc); + template bool isdigit (charT c, const locale& loc); + template bool ispunct (charT c, const locale& loc); + template bool isxdigit(charT c, const locale& loc); + template bool isalnum (charT c, const locale& loc); + template bool isgraph (charT c, const locale& loc); + template bool isblank (charT c, const locale& loc); + template charT toupper(charT c, const locale& loc); + template charT tolower(charT c, const locale& loc); // \ref{category.ctype}, ctype class ctype_base; - template class ctype; - template <> class ctype; // specialization - template class ctype_byname; + template class ctype; + template<> class ctype; // specialization + template class ctype_byname; class codecvt_base; - template class codecvt; - template class codecvt_byname; + template class codecvt; + template class codecvt_byname; // \ref{category.numeric}, numeric - template > + template> class num_get; - template > + template> class num_put; - template + template class numpunct; - template + template class numpunct_byname; // \ref{category.collate}, collation - template class collate; - template class collate_byname; + template class collate; + template class collate_byname; // \ref{category.time}, date and time class time_base; - template > + template> class time_get; - template > + template> class time_get_byname; - template > + template> class time_put; - template > + template> class time_put_byname; // \ref{category.monetary}, money class money_base; - template > + template> class money_get; - template > + template> class money_put; - template + template class moneypunct; - template + template class moneypunct_byname; // \ref{category.messages}, message retrieval class messages_base; - template class messages; - template class messages_byname; + template class messages; + template class messages_byname; } \end{codeblock} @@ -108,21 +107,19 @@ the information peculiar to a locale.\footnote{In this subclause, the type name \tcode{struct tm} is an incomplete type that is defined in -\indextext{\idxhdr{ctime}}% -\indexlibrary{\idxhdr{ctime}}% +\indexhdr{ctime}% \tcode{}.} \rSec1[locales]{Locales} \rSec2[locale]{Class \tcode{locale}} -\indextext{\idxhdr{locale}}% -\indexlibrary{\idxhdr{locale}}% +\indexhdr{locale}% \begin{codeblock} namespace std { class locale { public: - // types: + // types class facet; class id; using category = int; @@ -133,30 +130,30 @@ time = 0x100, messages = 0x200, all = collate | ctype | monetary | numeric | time | messages; - // construct/copy/destroy: + // construct/copy/destroy locale() noexcept; locale(const locale& other) noexcept; explicit locale(const char* std_name); explicit locale(const string& std_name); locale(const locale& other, const char* std_name, category); locale(const locale& other, const string& std_name, category); - template locale(const locale& other, Facet* f); + template locale(const locale& other, Facet* f); locale(const locale& other, const locale& one, category); ~locale(); // not virtual const locale& operator=(const locale& other) noexcept; - template locale combine(const locale& other) const; + template locale combine(const locale& other) const; - // locale operations: + // locale operations basic_string name() const; bool operator==(const locale& other) const; bool operator!=(const locale& other) const; - template + template bool operator()(const basic_string& s1, const basic_string& s2) const; - // global locale objects: + // global locale objects static locale global(const locale&); static const locale& classic(); }; @@ -190,14 +187,14 @@ \tcode{ostreambuf_iterator}.} \begin{codeblock} -template +template basic_ostream& operator<< (basic_ostream& s, Date d) { typename basic_ostream::sentry cerberos(s); if (cerberos) { ios_base::iostate err = ios_base::iostate::goodbit; tm tmbuf; d.extract(tmbuf); - use_facet> >( + use_facet>>( s.getloc()).put(s, s, s.fill(), err, &tmbuf, 'x'); s.setstate(err); // might throw } @@ -217,7 +214,7 @@ locale, it throws the standard exception \tcode{bad_cast}. -A \Cpp program can check if a locale implements a particular +A \Cpp{} program can check if a locale implements a particular facet with the function template \tcode{has_facet()}. @@ -246,7 +243,7 @@ and \tcode{isspace()}, so that given a locale -object \tcode{loc} a \Cpp program can call +object \tcode{loc} a \Cpp{} program can call \tcode{isspace(c, loc)}. (This eases upgrading existing extractors\iref{istream.formatted}.) \end{itemize} @@ -684,7 +681,7 @@ \indexlibrary{\idxcode{locale}!constructor}% \begin{itemdecl} -template locale(const locale& other, Facet* f); +template locale(const locale& other, Facet* f); \end{itemdecl} \begin{itemdescr} @@ -750,7 +747,7 @@ \indexlibrarymember{locale}{combine}% \begin{itemdecl} -template locale combine(const locale& other) const; +template locale combine(const locale& other) const; \end{itemdecl} \begin{itemdescr} @@ -822,7 +819,7 @@ \indexlibrarymember{locale}{operator()}% \begin{itemdecl} -template +template bool operator()(const basic_string& s1, const basic_string& s2) const; \end{itemdecl} @@ -923,7 +920,7 @@ \indexlibrarymember{locale}{use_facet}% \begin{itemdecl} -template const Facet& use_facet(const locale& loc); +template const Facet& use_facet(const locale& loc); \end{itemdecl} \begin{itemdescr} @@ -954,7 +951,7 @@ \indexlibrarymember{locale}{has_facet}% \begin{itemdecl} -template bool has_facet(const locale& loc) noexcept; +template bool has_facet(const locale& loc) noexcept; \end{itemdecl} \begin{itemdescr} @@ -980,18 +977,18 @@ \indexlibrary{\idxcode{isgraph}}% \indexlibrary{\idxcode{isblank}}% \begin{itemdecl} -template bool isspace (charT c, const locale& loc); -template bool isprint (charT c, const locale& loc); -template bool iscntrl (charT c, const locale& loc); -template bool isupper (charT c, const locale& loc); -template bool islower (charT c, const locale& loc); -template bool isalpha (charT c, const locale& loc); -template bool isdigit (charT c, const locale& loc); -template bool ispunct (charT c, const locale& loc); -template bool isxdigit(charT c, const locale& loc); -template bool isalnum (charT c, const locale& loc); -template bool isgraph (charT c, const locale& loc); -template bool isblank (charT c, const locale& loc); +template bool isspace (charT c, const locale& loc); +template bool isprint (charT c, const locale& loc); +template bool iscntrl (charT c, const locale& loc); +template bool isupper (charT c, const locale& loc); +template bool islower (charT c, const locale& loc); +template bool isalpha (charT c, const locale& loc); +template bool isdigit (charT c, const locale& loc); +template bool ispunct (charT c, const locale& loc); +template bool isxdigit(charT c, const locale& loc); +template bool isalnum (charT c, const locale& loc); +template bool isgraph (charT c, const locale& loc); +template bool isblank (charT c, const locale& loc); \end{itemdecl} \pnum @@ -1017,7 +1014,7 @@ \indexlibrary{\idxcode{toupper}}% \begin{itemdecl} -template charT toupper(charT c, const locale& loc); +template charT toupper(charT c, const locale& loc); \end{itemdecl} \begin{itemdescr} @@ -1028,7 +1025,7 @@ \indexlibrary{\idxcode{tolower}}% \begin{itemdecl} -template charT tolower(charT c, const locale& loc); +template charT tolower(charT c, const locale& loc); \end{itemdecl} \begin{itemdescr} @@ -1122,7 +1119,7 @@ \indexlibrary{\idxcode{ctype}}% \begin{codeblock} namespace std { - template + template class ctype : public locale::facet, public ctype_base { public: using char_type = charT; @@ -1515,7 +1512,7 @@ \indexlibrary{\idxcode{ctype_byname}}% \begin{codeblock} namespace std { - template + template class ctype_byname : public ctype { public: using mask = typename ctype::mask; @@ -1533,7 +1530,7 @@ \indexlibrary{\idxcode{ctype}}% \begin{codeblock} namespace std { - template <> + template<> class ctype : public locale::facet, public ctype_base { public: using char_type = char; @@ -1583,7 +1580,7 @@ is provided so that the member functions on type \tcode{char} can be implemented -\tcode{inline}.\footnote{Only the +inline.\footnote{Only the \tcode{char} (not \tcode{unsigned char} @@ -1831,7 +1828,7 @@ enum result { ok, partial, error, noconv }; }; - template + template class codecvt : public locale::facet, public codecvt_base { public: using intern_type = internT; @@ -2147,7 +2144,7 @@ \pnum \requires \tcode{(to <= to_end)} -well defined and \tcode{true}; state initialized, if at the beginning of a sequence, +well-defined and \tcode{true}; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence. @@ -2285,7 +2282,7 @@ \indexlibrary{\idxcode{codecvt_byname}}% \begin{codeblock} namespace std { - template + template class codecvt_byname : public codecvt { public: explicit codecvt_byname(const char*, size_t refs = 0); @@ -2351,7 +2348,7 @@ \indexlibrary{\idxcode{num_get}}% \begin{codeblock} namespace std { - template > + template> class num_get : public locale::facet { public: using char_type = charT; @@ -2765,7 +2762,7 @@ \indexlibrary{\idxcode{num_put}}% \begin{codeblock} namespace std { - template > + template> class num_put : public locale::facet { public: using char_type = charT; @@ -2987,9 +2984,10 @@ \stage{2} Any character \tcode{c} other than a decimal point(.) is converted to a -\tcode{charT} -via -\tcode{use_facet>(loc).widen( c )} +\tcode{charT} via +\begin{codeblock} +use_facet>(loc).widen(c) +\end{codeblock} A local variable \tcode{punct} is initialized via \begin{codeblock} @@ -3097,7 +3095,7 @@ \indexlibrary{\idxcode{numpunct}}% \begin{codeblock} namespace std { - template + template class numpunct : public locale::facet { public: using char_type = charT; @@ -3312,7 +3310,7 @@ \indexlibrary{\idxcode{numpunct_byname}}% \begin{codeblock} namespace std { - template + template class numpunct_byname : public numpunct { // this class is specialized for \tcode{char} and \tcode{wchar_t}. public: @@ -3335,7 +3333,7 @@ \indexlibrary{\idxcode{collate}}% \begin{codeblock} namespace std { - template + template class collate : public locale::facet { public: using char_type = charT; @@ -3483,7 +3481,7 @@ \indexlibrary{\idxcode{collate_byname}}% \begin{codeblock} namespace std { - template + template class collate_byname : public collate { public: using string_type = basic_string; @@ -3531,7 +3529,7 @@ enum dateorder { no_order, dmy, mdy, ymd, ydm }; }; - template > + template> class time_get : public locale::facet, public time_base { public: using char_type = charT; @@ -3938,7 +3936,7 @@ \indexlibrary{\idxcode{time_get_byname}}% \begin{codeblock} namespace std { - template > + template> class time_get_byname : public time_get { public: using dateorder = time_base::dateorder; @@ -3958,7 +3956,7 @@ \indexlibrary{\idxcode{time_put}}% \begin{codeblock} namespace std { - template > + template> class time_put : public locale::facet { public: using char_type = charT; @@ -4091,7 +4089,7 @@ \indexlibrary{\idxcode{time_put_byname}}% \begin{codeblock} namespace std { - template > + template> class time_put_byname : public time_put { public: using char_type = charT; @@ -4137,7 +4135,7 @@ \indexlibrary{\idxcode{money_get}}% \begin{codeblock} namespace std { - template > + template> class money_get : public locale::facet { public: using char_type = charT; @@ -4363,7 +4361,7 @@ \indexlibrary{\idxcode{money_put}}% \begin{codeblock} namespace std { - template > + template> class money_put : public locale::facet { public: using char_type = charT; @@ -4517,7 +4515,7 @@ struct pattern { char field[4]; }; }; - template + template class moneypunct : public locale::facet, public money_base { public: using char_type = charT; @@ -4779,10 +4777,12 @@ \begin{itemdescr} \pnum \returns -A string to use as the currency identifier symbol.\footnote{For international -specializations (second template parameter -\tcode{true}) -this is typically four characters long, usually three letters and a space.} +A string to use as the currency identifier symbol. +\begin{note} +For specializations where the second template parameter is \tcode{true}, +this is typically four characters long: a three-letter code as specified +by ISO 4217 followed by a space. +\end{note} \end{itemdescr} \indexlibrarymember{moneypunct}{do_positive_sign}% @@ -4835,7 +4835,7 @@ initialized to \tcode{\{ symbol, sign, none, value \}}.\footnote{Note that the international symbol returned by -\tcode{do_curr_sym()} +\tcode{do_curr_symbol()} usually contains a space, itself; for example, \tcode{"USD "}.} \end{itemdescr} @@ -4845,7 +4845,7 @@ \indexlibrary{\idxcode{moneypunct_byname}}% \begin{codeblock} namespace std { - template + template class moneypunct_byname : public moneypunct { public: using pattern = money_base::pattern; @@ -4877,7 +4877,7 @@ using catalog = @\textit{unspecified signed integer type}@; }; - template + template class messages : public locale::facet, public messages_base { public: using char_type = charT; @@ -5021,7 +5021,7 @@ \indexlibrary{\idxcode{messages_byname}}% \begin{codeblock} namespace std { - template + template class messages_byname : public messages { public: using catalog = messages_base::catalog; @@ -5039,9 +5039,9 @@ \rSec2[facets.examples]{Program-defined facets} \pnum -A \Cpp program may define facets to be added to a locale and used identically as +A \Cpp{} program may define facets to be added to a locale and used identically as the built-in facets. -To create a new facet interface, \Cpp programs simply derive from +To create a new facet interface, \Cpp{} programs simply derive from \tcode{locale::facet} a class containing a static member: \tcode{static locale::id id}. @@ -5167,7 +5167,7 @@ A locale object may be extended with a new facet simply by constructing it with an instance of a class derived from \tcode{locale::facet}. -The only member a \Cpp program must define is the static member +The only member a \Cpp{} program must define is the static member \tcode{id}, which identifies your class interface as a new facet. @@ -5252,8 +5252,7 @@ \rSec2[clocale.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cassert}}% -\indexlibrary{\idxhdr{cassert}}% +\indexhdr{cassert}% \indexlibrary{\idxcode{lconv}}% \indexlibrary{\idxcode{setlocale}}% \indexlibrary{\idxcode{localeconv}}% @@ -5282,8 +5281,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{locale.h}}% -\indexlibrary{\idxhdr{locale.h}}% +\indexhdr{locale.h}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}. diff --git a/source/macros.tex b/source/macros.tex index a30a7efe8f..5330322bb0 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -113,6 +113,7 @@ % locations \newcommand{\indextext}[1]{\index[generalindex]{#1}} \newcommand{\indexlibrary}[1]{\index[libraryindex]{#1}} +\newcommand{\indexhdr}[1]{\indextext{\idxhdr{#1}}\index[headerindex]{\idxhdr{#1}}} \newcommand{\indexgram}[1]{\index[grammarindex]{#1}} % Collation helper: When building an index key, replace all macro definitions @@ -135,7 +136,7 @@ \let\omname\mname% \let\mname\idxmname% \let\oCpp\Cpp% -\let\Cpp\idxCpp +\let\Cpp\idxCpp% \let\oBreakableUnderscore\BreakableUnderscore% See the "underscore" package. \let\BreakableUnderscore\textunderscore% \edef\x{#1}% @@ -173,11 +174,11 @@ % Code and definitions embedded in text. \newcommand{\tcode}[1]{\CodeStylex{#1}} -\newcommand{\techterm}[1]{\textit{#1}\xspace} -\newcommand{\defnx}[2]{\indexdefn{#2}\textit{#1}\xspace} +\newcommand{\techterm}[1]{\textit{#1}} +\newcommand{\defnx}[2]{\indexdefn{#2}\textit{#1}} \newcommand{\defn}[1]{\defnx{#1}{#1}} -\newcommand{\term}[1]{\textit{#1}\xspace} -\newcommand{\grammarterm}[1]{\textit{#1}\xspace} +\newcommand{\term}[1]{\textit{#1}} +\newcommand{\grammarterm}[1]{\textit{#1}} \newcommand{\grammartermnc}[1]{\textit{#1}\nocorr} \newcommand{\placeholder}[1]{\textit{#1}} \newcommand{\placeholdernc}[1]{\textit{#1\nocorr}} @@ -188,18 +189,18 @@ %%-------------------------------------------------- %% Macros for funky text -\newcommand{\Cpp}{\texorpdfstring{C\kern-0.05em\protect\raisebox{.35ex}{\textsmaller[2]{+\kern-0.05em+}}}{C++}\xspace} -\newcommand{\CppIII}{\Cpp 2003\xspace} -\newcommand{\CppXI}{\Cpp 2011\xspace} -\newcommand{\CppXIV}{\Cpp 2014\xspace} -\newcommand{\CppXVII}{\Cpp 2017\xspace} -\newcommand{\opt}{{\ensuremath{_\mathit{opt}}}\xspace} +\newcommand{\Cpp}{\texorpdfstring{C\kern-0.05em\protect\raisebox{.35ex}{\textsmaller[2]{+\kern-0.05em+}}}{C++}} +\newcommand{\CppIII}{\Cpp{} 2003} +\newcommand{\CppXI}{\Cpp{} 2011} +\newcommand{\CppXIV}{\Cpp{} 2014} +\newcommand{\CppXVII}{\Cpp{} 2017} +\newcommand{\opt}[1]{\ifthenelse{\equal{#1}{}} + {\PackageError{main}{argument must not be empty}{}} + {#1\ensuremath{_\mathit{opt}}}} \newcommand{\dcr}{-{-}} \newcommand{\bigoh}[1]{\ensuremath{\mathscr{O}(#1)}} % Make all tildes a little larger to avoid visual similarity with hyphens. -% FIXME: Remove \tilde in favour of \~. -\renewcommand{\tilde}{\textasciitilde} \renewcommand{\~}{\textasciitilde} \let\OldTextAsciiTilde\textasciitilde \renewcommand{\textasciitilde}{\protect\raisebox{-0.17ex}{\larger\OldTextAsciiTilde}} @@ -217,12 +218,12 @@ %% Notes and examples \newcommand{\noteintro}[1]{[\,\textit{#1:}\space} \newcommand{\noteoutro}[1]{\textit{\,---\,end #1}\,]} -\newenvironment{note}[1][Note]{\noteintro{#1}}{\noteoutro{note}\xspace} -\newenvironment{example}[1][Example]{\noteintro{#1}}{\noteoutro{example}\xspace} +\newenvironment{note}[1][Note]{\noteintro{#1}}{\noteoutro{note}\space} +\newenvironment{example}[1][Example]{\noteintro{#1}}{\noteoutro{example}\space} %% Library function descriptions -\newcommand{\Fundescx}[1]{\textit{#1}\xspace} -\newcommand{\Fundesc}[1]{\Fundescx{#1:}} +\newcommand{\Fundescx}[1]{\textit{#1}} +\newcommand{\Fundesc}[1]{\Fundescx{#1:}\space} \newcommand{\required}{\Fundesc{Required behavior}} \newcommand{\requires}{\Fundesc{Requires}} \newcommand{\effects}{\Fundesc{Effects}} @@ -245,18 +246,19 @@ \newcommand{\templalias}{\Fundesc{Alias template}} %% Cross reference -\newcommand{\xref}{\textsc{See also:}\xspace} +\newcommand{\xref}{\textsc{See also:}\space} %% Inline parenthesized reference \newcommand{\iref}[1]{\nolinebreak[3] (\ref{#1})} %% NTBS, etc. -\newcommand{\NTS}[1]{\textsc{#1}\xspace} +\newcommand{\NTS}[1]{\textsc{#1}} \newcommand{\ntbs}{\NTS{ntbs}} \newcommand{\ntmbs}{\NTS{ntmbs}} -\newcommand{\ntwcs}{\NTS{ntwcs}} -\newcommand{\ntcxvis}{\NTS{ntc16s}} -\newcommand{\ntcxxxiis}{\NTS{ntc32s}} +% The following are currently unused: +% \newcommand{\ntwcs}{\NTS{ntwcs}} +% \newcommand{\ntcxvis}{\NTS{ntc16s}} +% \newcommand{\ntcxxxiis}{\NTS{ntc32s}} %% Code annotations \newcommand{\EXPO}[1]{\textit{#1}} @@ -301,14 +303,15 @@ \newcommand{\commentellip}{\tcode{/* ...\ */}} %% Ranges -\newcommand{\Range}[4]{\tcode{#1#3,\penalty2000{} #4#2}\xspace} +\newcommand{\Range}[4]{\tcode{#1#3,\penalty2000{} #4#2}} \newcommand{\crange}[2]{\Range{[}{]}{#1}{#2}} \newcommand{\brange}[2]{\Range{(}{]}{#1}{#2}} \newcommand{\orange}[2]{\Range{(}{)}{#1}{#2}} \newcommand{\range}[2]{\Range{[}{)}{#1}{#2}} %% Change descriptions -\newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\xspace} +\newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\space} +\newcommand{\diffref}[1]{\pnum\textbf{Affected subclause:} \ref{#1}} \newcommand{\change}{\diffdef{Change}} \newcommand{\rationale}{\diffdef{Rationale}} \newcommand{\effect}{\diffdef{Effect on original feature}} @@ -317,13 +320,12 @@ %% Miscellaneous \newcommand{\uniquens}{\placeholdernc{unique}} -\newcommand{\stage}[1]{\item{\textbf{Stage #1:}}\xspace} -\newcommand{\doccite}[1]{\textit{#1}\xspace} +\newcommand{\stage}[1]{\item[Stage #1:]} +\newcommand{\doccite}[1]{\textit{#1}} \newcommand{\cvqual}[1]{\textit{#1}} \newcommand{\cv}{\cvqual{cv}} -\renewcommand{\emph}[1]{\textit{#1}\xspace} -\newcommand{\numconst}[1]{\textsl{#1}\xspace} -\newcommand{\logop}[1]{{\footnotesize #1}\xspace} +\newcommand{\numconst}[1]{\textsl{#1}} +\newcommand{\logop}[1]{{\footnotesize #1}} %%-------------------------------------------------- %% Environments for code listings. @@ -359,6 +361,9 @@ \lstnewenvironment{codeblock}{\CodeBlockSetup}{} +% An environment for command / program output that is not C++ code. +\lstnewenvironment{outputblock}{\lstset{language=}}{} + % A code block in which single-quotes are digit separators % rather than character literals. \lstnewenvironment{codeblockdigitsep}{ @@ -416,7 +421,7 @@ \newenvironment{bnfbase} { \newcommand{\nontermdef}[1]{{\BnfNontermshape##1\itcorr}\indexgrammar{\idxgram{##1}}\textnormal{:}} - \newcommand{\terminal}[1]{{\BnfTermshape ##1}\xspace} + \newcommand{\terminal}[1]{{\BnfTermshape ##1}} \newcommand{\descr}[1]{\textnormal{##1}} \newcommand{\bnfindentfirst}{\BnfIndent} \newcommand{\bnfindentinc}{\BnfInc} @@ -429,13 +434,13 @@ \nonfrenchspacing } -\newenvironment{BnfTabBase}[1] +\newenvironment{BnfTabBase}[2] { \begin{bnfbase} #1 \begin{indented} \begin{tabbing} - \hspace*{\bnfindentfirst}\=\hspace{\bnfindentinc}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\kill} + \hspace*{\bnfindentfirst}\=\hspace{#2}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\hspace{.6in}\=\kill} { \end{tabbing} \end{indented} @@ -444,7 +449,7 @@ \newenvironment{bnfkeywordtab} { - \begin{BnfTabBase}{\BnfTermshape} + \begin{BnfTabBase}{\BnfTermshape}{.6in} } { \end{BnfTabBase} @@ -452,7 +457,7 @@ \newenvironment{bnftab} { - \begin{BnfTabBase}{\BnfNontermshape} + \begin{BnfTabBase}{\BnfNontermshape}{\bnfindentinc} } { \end{BnfTabBase} @@ -554,4 +559,4 @@ \let\addcontentsline\oldcontentsline% } \newcommand{\defncontext}[1]{\textlangle#1\textrangle} -\newenvironment{defnote}{\addtocounter{termnote}{1}\noteintro{Note \thetermnote{} to entry}}{\noteoutro{note}\xspace} +\newenvironment{defnote}{\addtocounter{termnote}{1}\noteintro{Note \thetermnote{} to entry}}{\noteoutro{note}\space} diff --git a/source/numerics.tex b/source/numerics.tex index 7cc2e2aec5..317d8fb342 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -4,7 +4,7 @@ \rSec1[numerics.general]{General} \pnum -This Clause describes components that \Cpp programs may use to perform +This Clause describes components that \Cpp{} programs may use to perform seminumerical operations. \pnum @@ -59,7 +59,7 @@ and \tcode{valarray} components are parameterized by the type of information they contain and manipulate. -A \Cpp program shall instantiate these components only with a type +A \Cpp{} program shall instantiate these components only with a type \tcode{T} that satisfies the following requirements:\footnote{In other words, value types. @@ -151,8 +151,7 @@ \rSec1[cfenv]{The floating-point environment} \rSec2[cfenv.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cfenv}}% -\indexlibrary{\idxhdr{cfenv}}% +\indexhdr{cfenv}% \indexlibrary{\idxcode{fenv_t}}% \indexlibrary{\idxcode{fexcept_t}}% @@ -249,8 +248,7 @@ \pnum The header -\indextext{\idxhdr{complex}}% -\indexlibrary{\idxhdr{complex}}% +\indexhdr{complex}% \tcode{} defines a class template, @@ -288,41 +286,38 @@ \rSec2[complex.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{complex}}% -\indexlibrary{\idxhdr{complex}}% +\indexhdr{complex}% \begin{codeblock} namespace std { + // \ref{complex}, class template \tcode{complex} template class complex; + + // \ref{complex.special}, \tcode{complex} specializations template<> class complex; template<> class complex; template<> class complex; // \ref{complex.ops}, operators - template - complex operator+(const complex&, const complex&); - template complex operator+(const complex&, const T&); - template complex operator+(const T&, const complex&); - - template complex operator-( - const complex&, const complex&); - template complex operator-(const complex&, const T&); - template complex operator-(const T&, const complex&); - - template complex operator*( - const complex&, const complex&); - template complex operator*(const complex&, const T&); - template complex operator*(const T&, const complex&); - - template complex operator/( - const complex&, const complex&); - template complex operator/(const complex&, const T&); - template complex operator/(const T&, const complex&); - - template complex operator+(const complex&); - template complex operator-(const complex&); - - template constexpr bool operator==( - const complex&, const complex&); + template constexpr complex operator+(const complex&, const complex&); + template constexpr complex operator+(const complex&, const T&); + template constexpr complex operator+(const T&, const complex&); + + template constexpr complex operator-(const complex&, const complex&); + template constexpr complex operator-(const complex&, const T&); + template constexpr complex operator-(const T&, const complex&); + + template constexpr complex operator*(const complex&, const complex&); + template constexpr complex operator*(const complex&, const T&); + template constexpr complex operator*(const T&, const complex&); + + template constexpr complex operator/(const complex&, const complex&); + template constexpr complex operator/(const complex&, const T&); + template constexpr complex operator/(const T&, const complex&); + + template constexpr complex operator+(const complex&); + template constexpr complex operator-(const complex&); + + template constexpr bool operator==(const complex&, const complex&); template constexpr bool operator==(const complex&, const T&); template constexpr bool operator==(const T&, const complex&); @@ -342,11 +337,11 @@ template T abs(const complex&); template T arg(const complex&); - template T norm(const complex&); + template constexpr T norm(const complex&); - template complex conj(const complex&); + template constexpr complex conj(const complex&); template complex proj(const complex&); - template complex polar(const T&, const T& = 0); + template complex polar(const T&, const T& = T()); // \ref{complex.transcendentals}, transcendentals template complex acos(const complex&); @@ -390,6 +385,7 @@ \rSec2[complex]{Class template \tcode{complex}} \indexlibrary{\idxcode{complex}}% +\indexlibrarymember{value_type}{complex}% \begin{codeblock} namespace std { template class complex { @@ -401,22 +397,22 @@ template constexpr complex(const complex&); constexpr T real() const; - void real(T); + constexpr void real(T); constexpr T imag() const; - void imag(T); - - complex& operator= (const T&); - complex& operator+=(const T&); - complex& operator-=(const T&); - complex& operator*=(const T&); - complex& operator/=(const T&); - - complex& operator=(const complex&); - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + constexpr void imag(T); + + constexpr complex& operator= (const T&); + constexpr complex& operator+=(const T&); + constexpr complex& operator-=(const T&); + constexpr complex& operator*=(const T&); + constexpr complex& operator/=(const T&); + + constexpr complex& operator=(const complex&); + template constexpr complex& operator= (const complex&); + template constexpr complex& operator+=(const complex&); + template constexpr complex& operator-=(const complex&); + template constexpr complex& operator*=(const complex&); + template constexpr complex& operator/=(const complex&); }; } \end{codeblock} @@ -445,22 +441,22 @@ constexpr explicit complex(const complex&); constexpr float real() const; - void real(float); + constexpr void real(float); constexpr float imag() const; - void imag(float); - - complex& operator= (float); - complex& operator+=(float); - complex& operator-=(float); - complex& operator*=(float); - complex& operator/=(float); - - complex& operator=(const complex&); - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + constexpr void imag(float); + + constexpr complex& operator= (float); + constexpr complex& operator+=(float); + constexpr complex& operator-=(float); + constexpr complex& operator*=(float); + constexpr complex& operator/=(float); + + constexpr complex& operator=(const complex&); + template constexpr complex& operator= (const complex&); + template constexpr complex& operator+=(const complex&); + template constexpr complex& operator-=(const complex&); + template constexpr complex& operator*=(const complex&); + template constexpr complex& operator/=(const complex&); }; template<> class complex { @@ -472,22 +468,22 @@ constexpr explicit complex(const complex&); constexpr double real() const; - void real(double); + constexpr void real(double); constexpr double imag() const; - void imag(double); - - complex& operator= (double); - complex& operator+=(double); - complex& operator-=(double); - complex& operator*=(double); - complex& operator/=(double); - - complex& operator=(const complex&); - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + constexpr void imag(double); + + constexpr complex& operator= (double); + constexpr complex& operator+=(double); + constexpr complex& operator-=(double); + constexpr complex& operator*=(double); + constexpr complex& operator/=(double); + + constexpr complex& operator=(const complex&); + template constexpr complex& operator= (const complex&); + template constexpr complex& operator+=(const complex&); + template constexpr complex& operator-=(const complex&); + template constexpr complex& operator*=(const complex&); + template constexpr complex& operator/=(const complex&); }; template<> class complex { @@ -499,22 +495,22 @@ constexpr complex(const complex&); constexpr long double real() const; - void real(long double); + constexpr void real(long double); constexpr long double imag() const; - void imag(long double); - - complex& operator=(const complex&); - complex& operator= (long double); - complex& operator+=(long double); - complex& operator-=(long double); - complex& operator*=(long double); - complex& operator/=(long double); - - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + constexpr void imag(long double); + + constexpr complex& operator= (long double); + constexpr complex& operator+=(long double); + constexpr complex& operator-=(long double); + constexpr complex& operator*=(long double); + constexpr complex& operator/=(long double); + + constexpr complex& operator=(const complex&); + template constexpr complex& operator= (const complex&); + template constexpr complex& operator+=(const complex&); + template constexpr complex& operator-=(const complex&); + template constexpr complex& operator*=(const complex&); + template constexpr complex& operator/=(const complex&); }; } \end{codeblock} @@ -549,7 +545,7 @@ \indexlibrarymember{real}{complex}% \begin{itemdecl} -void real(T val); +constexpr void real(T val); \end{itemdecl} \begin{itemdescr} @@ -569,7 +565,7 @@ \indexlibrarymember{imag}{complex}% \begin{itemdecl} -void imag(T val); +constexpr void imag(T val); \end{itemdecl} \begin{itemdescr} @@ -581,7 +577,7 @@ \indexlibrarymember{operator+=}{complex}% \begin{itemdecl} -complex& operator+=(const T& rhs); +constexpr complex& operator+=(const T& rhs); \end{itemdecl} \begin{itemdescr} @@ -600,7 +596,7 @@ \indexlibrarymember{operator-=}{complex}% \begin{itemdecl} -complex& operator-=(const T& rhs); +constexpr complex& operator-=(const T& rhs); \end{itemdecl} \begin{itemdescr} @@ -619,7 +615,7 @@ \indexlibrarymember{operator*=}{complex}% \begin{itemdecl} -complex& operator*=(const T& rhs); +constexpr complex& operator*=(const T& rhs); \end{itemdecl} \begin{itemdescr} @@ -637,7 +633,7 @@ \indexlibrarymember{operator/=}{complex}% \begin{itemdecl} -complex& operator/=(const T& rhs); +constexpr complex& operator/=(const T& rhs); \end{itemdecl} \begin{itemdescr} @@ -655,7 +651,7 @@ \indexlibrarymember{operator+=}{complex}% \begin{itemdecl} -template complex& operator+=(const complex& rhs); +template constexpr complex& operator+=(const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -673,7 +669,7 @@ \indexlibrarymember{operator-=}{complex}% \begin{itemdecl} -template complex& operator-=(const complex& rhs); +template constexpr complex& operator-=(const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -691,7 +687,7 @@ \indexlibrarymember{operator*=}{complex}% \begin{itemdecl} -template complex& operator*=(const complex& rhs); +template constexpr complex& operator*=(const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -709,7 +705,7 @@ \indexlibrarymember{operator/=}{complex}% \begin{itemdecl} -template complex& operator/=(const complex& rhs); +template constexpr complex& operator/=(const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -729,7 +725,7 @@ \indexlibrarymember{operator+}{complex}% \begin{itemdecl} -template complex operator+(const complex& lhs); +template constexpr complex operator+(const complex& lhs); \end{itemdecl} \begin{itemdescr} @@ -743,9 +739,9 @@ \end{itemdescr} \begin{itemdecl} -template complex operator+(const complex& lhs, const complex& rhs); -template complex operator+(const complex& lhs, const T& rhs); -template complex operator+(const T& lhs, const complex& rhs); +template constexpr complex operator+(const complex& lhs, const complex& rhs); +template constexpr complex operator+(const complex& lhs, const T& rhs); +template constexpr complex operator+(const T& lhs, const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -756,7 +752,7 @@ \indexlibrarymember{operator-}{complex}% \begin{itemdecl} -template complex operator-(const complex& lhs); +template constexpr complex operator-(const complex& lhs); \end{itemdecl} \begin{itemdescr} @@ -771,9 +767,9 @@ \indexlibrarymember{operator-}{complex}% \begin{itemdecl} -template complex operator-(const complex& lhs, const complex& rhs); -template complex operator-(const complex& lhs, const T& rhs); -template complex operator-(const T& lhs, const complex& rhs); +template constexpr complex operator-(const complex& lhs, const complex& rhs); +template constexpr complex operator-(const complex& lhs, const T& rhs); +template constexpr complex operator-(const T& lhs, const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -784,9 +780,9 @@ \indexlibrarymember{operator*}{complex}% \begin{itemdecl} -template complex operator*(const complex& lhs, const complex& rhs); -template complex operator*(const complex& lhs, const T& rhs); -template complex operator*(const T& lhs, const complex& rhs); +template constexpr complex operator*(const complex& lhs, const complex& rhs); +template constexpr complex operator*(const complex& lhs, const T& rhs); +template constexpr complex operator*(const T& lhs, const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -797,9 +793,9 @@ \indexlibrarymember{operator/}{complex}% \begin{itemdecl} -template complex operator/(const complex& lhs, const complex& rhs); -template complex operator/(const complex& lhs, const T& rhs); -template complex operator/(const T& lhs, const complex& rhs); +template constexpr complex operator/(const complex& lhs, const complex& rhs); +template constexpr complex operator/(const complex& lhs, const T& rhs); +template constexpr complex operator/(const T& lhs, const complex& rhs); \end{itemdecl} \begin{itemdescr} @@ -964,7 +960,7 @@ \indexlibrary{\idxcode{norm}!\idxcode{complex}}% \begin{itemdecl} -template T norm(const complex& x); +template constexpr T norm(const complex& x); \end{itemdecl} \begin{itemdescr} @@ -975,7 +971,7 @@ \indexlibrary{\idxcode{conj}!\idxcode{complex}}% \begin{itemdecl} -template complex conj(const complex& x); +template constexpr complex conj(const complex& x); \end{itemdecl} \begin{itemdescr} @@ -995,12 +991,13 @@ \pnum \remarks -Behaves the same as the C function \tcode{cproj}, defined in 7.3.9.4. +Behaves the same as the C function \tcode{cproj}. +\xref ISO C 7.3.9.5 \end{itemdescr} \indexlibrary{\idxcode{polar}!\idxcode{complex}}% \begin{itemdecl} -template complex polar(const T& rho, const T& theta = 0); +template complex polar(const T& rho, const T& theta = T()); \end{itemdecl} \begin{itemdescr} @@ -1031,8 +1028,8 @@ \pnum \remarks -Behaves the same as C function \tcode{cacos}, -defined in 7.3.5.1. +Behaves the same as the C function \tcode{cacos}. +\xref ISO C 7.3.5.1 \end{itemdescr} \indexlibrary{\idxcode{asin}!\idxcode{complex}}% @@ -1047,8 +1044,8 @@ \pnum \remarks -Behaves the same as C function \tcode{casin}, -defined in 7.3.5.2. +Behaves the same as the C function \tcode{casin}. +\xref ISO C 7.3.5.2 \end{itemdescr} \indexlibrary{\idxcode{atan}!\idxcode{complex}}% @@ -1063,8 +1060,8 @@ \pnum \remarks -Behaves the same as C function \tcode{catan}, -defined in 7.3.5.3. +Behaves the same as the C function \tcode{catan}. +\xref ISO C 7.3.5.3 \end{itemdescr} \indexlibrary{\idxcode{acosh}!\idxcode{complex}}% @@ -1079,8 +1076,8 @@ \pnum \remarks -Behaves the same as C function \tcode{cacosh}, -defined in 7.3.6.1. +Behaves the same as the C function \tcode{cacosh}. +\xref ISO C 7.3.6.1 \end{itemdescr} \indexlibrary{\idxcode{asinh}!\idxcode{complex}}% @@ -1095,8 +1092,8 @@ \pnum \remarks -Behaves the same as C function \tcode{casinh}, -defined in 7.3.6.2. +Behaves the same as the C function \tcode{casinh}. +\xref ISO C 7.3.6.2 \end{itemdescr} \indexlibrary{\idxcode{atanh}!\idxcode{complex}}% @@ -1111,8 +1108,8 @@ \pnum \remarks -Behaves the same as C function \tcode{catanh}, -defined in 7.3.6.3. +Behaves the same as the C function \tcode{catanh}. +\xref ISO C 7.3.6.3 \end{itemdescr} \indexlibrary{\idxcode{cos}!\idxcode{complex}}% @@ -1159,7 +1156,7 @@ The complex natural (base-$e$) logarithm of \tcode{x}. For all \tcode{x}, \tcode{imag(log(x))} lies in the interval \crange{$-\pi$}{$\pi$}. \begin{note} -The semantics of this function are intended to be the same in \Cpp +The semantics of this function are intended to be the same in \Cpp{} as they are for \tcode{clog} in C. \end{note} @@ -1239,7 +1236,7 @@ The complex square root of \tcode{x}, in the range of the right half-plane. \begin{note} -The semantics of this function are intended to be the same in \Cpp +The semantics of this function are intended to be the same in \Cpp{} as they are for \tcode{csqrt} in C. \end{note} @@ -1284,26 +1281,27 @@ conj proj imag real \end{codeblock} +where \tcode{norm}, \tcode{conj}, \tcode{imag}, and \tcode{real} are \tcode{constexpr} overloads. \pnum \indextext{overloads!floating-point}% The additional overloads shall be sufficient to ensure: -\begin{enumerate} +\begin{itemize} \item If the argument has type \tcode{long double}, then it is effectively cast to \tcode{complex}. \item Otherwise, if the argument has type \tcode{double} or an integer type, then it is effectively cast to \tcode{complex<\brk{}double>}. \item Otherwise, if the argument has type \tcode{float}, then it is effectively cast to \tcode{complex}. -\end{enumerate} +\end{itemize} \pnum \indexlibrary{\idxcode{pow}}% Function template \tcode{pow} shall have additional overloads sufficient to ensure, for a call with at least one argument of type \tcode{complex}: -\begin{enumerate} +\begin{itemize} \item If either argument has type \tcode{complex} or type \tcode{long double}, then both arguments are effectively cast to @@ -1313,14 +1311,14 @@ \tcode{complex}. \item Otherwise, if either argument has type \tcode{complex} or \tcode{float}, then both arguments are effectively cast to \tcode{complex}. -\end{enumerate} +\end{itemize} \rSec2[complex.literals]{Suffixes for complex number literals} \indexlibrary{complex!literals}% \indexlibrary{literals!complex}% \pnum -This section describes literal suffixes for constructing complex number literals. +This subclause describes literal suffixes for constructing complex number literals. The suffixes \tcode{i}, \tcode{il}, and \tcode{if} create complex numbers of the types \tcode{complex}, \tcode{complex}, and \tcode{complex} respectively, with their imaginary part denoted by the @@ -1452,7 +1450,7 @@ \begin{enumeratea} \item - the operator \rightshift\xspace + the operator \rightshift{} denotes a bitwise right shift with zero-valued bits appearing in the high bits of the result, and @@ -1467,7 +1465,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Requirements section +%% Requirements subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1477,7 +1475,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% general requirements section +%% general requirements subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1587,8 +1585,8 @@ in Table~\ref{tab:SeedSequence} are valid and have the indicated semantics, and if \tcode{S} also satisfies all other requirements -of this section \ref{rand.req.seedseq}. -In that Table and throughout this section: +of this subclause \ref{rand.req.seedseq}. +In that Table and throughout this subclause: \begin{enumeratea} \item \tcode{T} is the type named by @@ -1728,8 +1726,8 @@ in Table~\ref{tab:UniformRandomBitGenerator} are valid and have the indicated semantics, and if \tcode{G} also satisfies all other requirements -of this section \ref{rand.req.urng}. -In that Table and throughout this section: +of this subclause \ref{rand.req.urng}. +In that Table and throughout this subclause: \begin{enumeratea} \item \tcode{T} is the type named by @@ -1806,7 +1804,7 @@ is a uniform random bit generator that additionally meets the requirements (e.g., for seeding and for input/output) -specified in this section. +specified in this subclause. \pnum At any given time, @@ -1852,8 +1850,8 @@ in Table~\ref{tab:RandomEngine} are valid and have the indicated semantics, and if \tcode{E} also satisfies all other requirements -of this section \ref{rand.req.eng}. -In that Table and throughout this section: +of this subclause \ref{rand.req.eng}. +In that Table and throughout this subclause: \begin{enumeratea} \item \tcode{T} is the type named by @@ -2236,8 +2234,8 @@ are valid and have the indicated semantics, and if \tcode{D} and its associated types also satisfy all other requirements -of this section \ref{rand.req.dist}. -In that Table and throughout this section, +of this subclause \ref{rand.req.dist}. +In that Table and throughout this subclause, \begin{enumeratea} \item \tcode{T} is the type named by @@ -2499,15 +2497,14 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Header synopsis section +%% Header synopsis subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \rSec2[rand.synopsis]{Header \tcode{} synopsis}% -\indextext{\idxhdr{random}|(}% -\indexlibrary{\idxhdr{random}|(}% +\indexhdr{random} \indextext{random number generation!synopsis|(} \begin{codeblock} @@ -2645,14 +2642,12 @@ } \end{codeblock}% \indextext{random number generation!synopsis|)}% -\indextext{\idxhdr{random}|)}% -\indexlibrary{\idxhdr{random}|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Engine class templates section +%% Engine class templates subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2663,30 +2658,30 @@ \pnum Each type instantiated -from a class template specified in this section~\ref{rand.eng} +from a class template specified in this subclause~\ref{rand.eng} satisfies the requirements of a random number engine\iref{rand.req.eng} type. \pnum Except where specified otherwise, the complexity of each function -specified in this section~\ref{rand.eng} +specified in this subclause~\ref{rand.eng} is constant. \pnum Except where specified otherwise, -no function described in this section~\ref{rand.eng} +no function described in this subclause~\ref{rand.eng} throws an exception. \pnum -Every function described in this section~\ref{rand.eng} +Every function described in this subclause~\ref{rand.eng} that has a function parameter \tcode{q} of type \tcode{Sseq\&} for a template type parameter named \tcode{Sseq} that is different from type \tcode{seed_seq} throws what and when the invocation of \tcode{q.generate} throws. \pnum -Descriptions are provided in this section~\ref{rand.eng} +Descriptions are provided in this subclause~\ref{rand.eng} only for engine operations that are not described in \ref{rand.req.eng} or for operations where there is additional semantic information. @@ -2698,7 +2693,7 @@ are not shown in the synopses. \pnum -Each template specified in this section~\ref{rand.eng} +Each template specified in this subclause~\ref{rand.eng} requires one or more relationships, involving the value(s) of its non-type template parameter(s), to hold. A program instantiating any of these templates @@ -2713,7 +2708,7 @@ \item if the constructor \begin{codeblock} -template explicit X(Sseq& q); +template explicit X(Sseq& q); \end{codeblock} is called with a type \tcode{Sseq} that does not qualify as a seed sequence, then this constructor shall not participate in overload resolution; @@ -2721,7 +2716,7 @@ \item if the member function \begin{codeblock} -template void seed(Sseq& q); +template void seed(Sseq& q); \end{codeblock} is called with a type \tcode{Sseq} that does not qualify as a seed sequence, then this function shall not participate in overload resolution. @@ -2790,7 +2785,7 @@ If the template parameter \tcode{m} is $0$, the modulus $m$ -used throughout this section~\ref{rand.eng.lcong} +used throughout this subclause~\ref{rand.eng.lcong} \indextext{\idxcode{linear_congruential_engine}!modulus} is \tcode{numeric_limits::max()} plus $1$. \begin{note} @@ -3201,7 +3196,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Engine adaptors class templates section +%% Engine adaptors class templates subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3213,32 +3208,32 @@ \pnum Each type instantiated -from a class template specified in this section~\ref{rand.adapt} +from a class template specified in this subclause~\ref{rand.adapt} satisfies the requirements of a random number engine adaptor\iref{rand.req.adapt} type. \pnum Except where specified otherwise, the complexity of each function -specified in this section~\ref{rand.adapt} +specified in this subclause~\ref{rand.adapt} is constant. \pnum Except where specified otherwise, -no function described in this section~\ref{rand.adapt} +no function described in this subclause~\ref{rand.adapt} throws an exception. \pnum -Every function described in this section~\ref{rand.adapt} +Every function described in this subclause~\ref{rand.adapt} that has a function parameter \tcode{q} of type \tcode{Sseq\&} for a template type parameter named \tcode{Sseq} that is different from type \tcode{seed_seq} throws what and when the invocation of \tcode{q.generate} throws. \pnum -Descriptions are provided in this section~\ref{rand.adapt} +Descriptions are provided in this subclause~\ref{rand.adapt} only for adaptor operations -that are not described in section~\ref{rand.req.adapt} +that are not described in subclause~\ref{rand.req.adapt} or for operations where there is additional semantic information. In particular, declarations for copy constructors, @@ -3248,7 +3243,7 @@ are not shown in the synopses. \pnum -Each template specified in this section~\ref{rand.adapt} +Each template specified in this subclause~\ref{rand.adapt} requires one or more relationships, involving the value(s) of its non-type template parameter(s), to hold. A program instantiating any of these templates @@ -3352,7 +3347,7 @@ \pnum In addition to its behavior -pursuant to section~\ref{rand.req.adapt}, +pursuant to subclause~\ref{rand.req.adapt}, each constructor% \indexlibrary{\idxcode{discard_block_engine}!constructor} that is not a copy constructor @@ -3605,7 +3600,7 @@ \pnum In addition to its behavior -pursuant to section~\ref{rand.req.adapt}, +pursuant to subclause~\ref{rand.req.adapt}, each constructor% \indexlibrary{\idxcode{shuffle_order_engine}!constructor} that is not a copy constructor @@ -3618,7 +3613,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Engines with predefined parameters section +%% Engines with predefined parameters subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3805,7 +3800,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% random_device class section +%% random_device class subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3917,7 +3912,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% utilities section +%% utilities subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -4154,7 +4149,7 @@ \pnum Each function instantiated from the template - described in this section~\ref{rand.util.canonical} + described in this subclause~\ref{rand.util.canonical} maps the result of one or more invocations of a supplied uniform random bit generator \tcode{g} to one member @@ -4220,7 +4215,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Distribution class templates section +%% Distribution class templates subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -4233,12 +4228,12 @@ \pnum Each type instantiated -from a class template specified in this section~\ref{rand.dist} +from a class template specified in this subclause~\ref{rand.dist} satisfies the requirements of a random number distribution\iref{rand.req.dist} type. \pnum -Descriptions are provided in this section~\ref{rand.dist} +Descriptions are provided in this subclause~\ref{rand.dist} only for distribution operations that are not described in \ref{rand.req.dist} or for operations where there is additional semantic information. @@ -4257,13 +4252,13 @@ \pnum The value of each probability density function $p(z)$ and of each discrete probability function $P(z_i)$ -specified in this section +specified in this subclause is $0$ everywhere outside its stated domain. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Uniform distributions section +%% Uniform distributions subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -4451,7 +4446,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Bernoulli distributions section +%% Bernoulli distributions subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -4788,7 +4783,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Poisson distributions section +%% Poisson distributions subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -5225,7 +5220,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Normal distributions section +%% Normal distributions subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -5762,7 +5757,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% Sampling distributions section +%% Sampling distributions subclause %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -6384,8 +6379,7 @@ \rSec2[c.math.rand]{Low-quality random number generation} \pnum -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% \begin{note} The header \tcode{}\iref{cstdlib.syn} declares the functions described in this subclause. @@ -6432,8 +6426,7 @@ \rSec1[numarray]{Numeric arrays} \rSec2[valarray.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{valarray}}% -\indexlibrary{\idxhdr{valarray}}% +\indexhdr{valarray}% \begin{codeblock} #include @@ -6541,10 +6534,10 @@ template valarray tan (const valarray&); template valarray tanh (const valarray&); - template @\unspec{1}@ begin(valarray& v); - template @\unspec{2}@ begin(const valarray& v); - template @\unspec{1}@ end(valarray& v); - template @\unspec{2}@ end(const valarray& v); + template @\unspec{1}@ begin(valarray& v); + template @\unspec{2}@ begin(const valarray& v); + template @\unspec{1}@ end(valarray& v); + template @\unspec{2}@ end(const valarray& v); } \end{codeblock} @@ -6746,12 +6739,6 @@ matrix class nor a field class. However, it is a very useful building block for designing such classes.} -\pnum -An implementation is permitted to qualify any of the functions declared in -\tcode{} -as -\tcode{inline}. - \rSec3[valarray.cons]{\tcode{valarray} constructors} \indexlibrary{\idxcode{valarray}!constructor}% @@ -7711,7 +7698,7 @@ \indexlibrarymember{swap}{valarray}% \begin{itemdecl} -template void swap(valarray& x, valarray& y) noexcept; +template void swap(valarray& x, valarray& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -7745,7 +7732,7 @@ Such a slice is specified by a starting index, a length, and a stride.\footnote{BLAS stands for \textit{Basic Linear Algebra Subprograms.} -\Cpp programs may instantiate this class. +\Cpp{} programs may instantiate this class. See, for example, Dongarra, Du Croz, Duff, and Hammerling: \textit{A set of Level 3 Basic Linear Algebra Subprograms}; @@ -7801,9 +7788,10 @@ \rSec3[template.slice.array.overview]{Class template \tcode{slice_array} overview} \indexlibrary{\idxcode{slice_array}}% +\indexlibrarymember{value_type}{slice_array}% \begin{codeblock} namespace std { - template class slice_array { + template class slice_array { public: using value_type = T; @@ -8057,7 +8045,7 @@ The constructor with arguments builds a \tcode{gslice} based on a specification of start, lengths, and strides, as explained -in the previous section. +in the previous subclause. \end{itemdescr} \rSec3[gslice.access]{\tcode{gslice} access functions} @@ -8086,9 +8074,10 @@ \rSec3[template.gslice.array.overview]{Class template \tcode{gslice_array} overview} \indexlibrary{\idxcode{gslice_array}}% +\indexlibrarymember{value_type}{gslice_array}% \begin{codeblock} namespace std { - template class gslice_array { + template class gslice_array { public: using value_type = T; @@ -8217,9 +8206,10 @@ \rSec3[template.mask.array.overview]{Class template \tcode{mask_array} overview} \indexlibrary{\idxcode{mask_array}}% +\indexlibrarymember{value_type}{mask_array}% \begin{codeblock} namespace std { - template class mask_array { + template class mask_array { public: using value_type = T; @@ -8342,9 +8332,10 @@ \rSec3[template.indirect.array.overview]{Class template \tcode{indirect_array} overview} \indexlibrary{\idxcode{indirect_array}}% +\indexlibrarymember{value_type}{indirect_array}% \begin{codeblock} namespace std { - template class indirect_array { + template class indirect_array { public: using value_type = T; @@ -8513,8 +8504,8 @@ \indexlibrary{\idxcode{begin}!\idxcode{valarray}}% \begin{itemdecl} -template @\unspec{1}@ begin(valarray& v); -template @\unspec{2}@ begin(const valarray& v); +template @\unspec{1}@ begin(valarray& v); +template @\unspec{2}@ begin(const valarray& v); \end{itemdecl} \begin{itemdescr} @@ -8524,8 +8515,8 @@ \indexlibrary{\idxcode{end}!\idxcode{valarray}}% \begin{itemdecl} -template @\unspec{1}@ end(valarray& v); -template @\unspec{2}@ end(const valarray& v); +template @\unspec{1}@ end(valarray& v); +template @\unspec{2}@ end(const valarray& v); \end{itemdecl} \begin{itemdescr} @@ -8538,14 +8529,13 @@ \rSec2[numeric.ops.overview]{Header \tcode{} synopsis} -\indextext{\idxhdr{numeric}}% -\indexlibrary{\idxhdr{numeric}}% +\indexhdr{numeric}% \begin{codeblock} namespace std { // \ref{accumulate}, accumulate - template + template T accumulate(InputIterator first, InputIterator last, T init); - template + template T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // \ref{reduce}, reduce @@ -8568,11 +8558,11 @@ ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); // \ref{inner.product}, inner product - template + template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); - template + template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, @@ -8619,11 +8609,11 @@ BinaryOperation binary_op, UnaryOperation unary_op); // \ref{partial.sum}, partial sum - template + template OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result); - template + template OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, @@ -8730,22 +8720,22 @@ T init); // \ref{adjacent.difference}, adjacent difference - template + template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); - template + template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); - template + template ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); - template + template ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, @@ -8753,15 +8743,15 @@ BinaryOperation binary_op); // \ref{numeric.iota}, iota - template + template void iota(ForwardIterator first, ForwardIterator last, T value); // \ref{numeric.ops.gcd}, greatest common divisor - template + template constexpr common_type_t gcd(M m, N n); // \ref{numeric.ops.lcm}, least common multiple - template + template constexpr common_type_t lcm(M m, N n); } \end{codeblock} @@ -8790,9 +8780,9 @@ \indexlibrary{\idxcode{accumulate}}% \begin{itemdecl} -template +template T accumulate(InputIterator first, InputIterator last, T init); -template +template T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); \end{itemdecl} @@ -8814,9 +8804,9 @@ with the initial value \tcode{init} and then modifies it with -\tcode{acc = acc + *i} +\tcode{acc = std::move(acc) + *i} or -\tcode{acc = binary_op(acc, *i)} +\tcode{acc = binary_op(std::move(acc), *i)} for every iterator \tcode{i} in the range \range{first}{last} @@ -8936,11 +8926,11 @@ \indexlibrary{\idxcode{inner_product}}% \begin{itemdecl} -template +template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); -template +template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, @@ -8968,9 +8958,9 @@ with the initial value \tcode{init} and then modifying it with -\tcode{acc = acc + (*i1) * (*i2)} +\tcode{acc = std::move(acc) + (*i1) * (*i2)} or -\tcode{acc = binary_op1(acc, binary_op2(*i1, *i2))} +\tcode{acc = binary_op1(std::move(acc), binary_op2(*i1, *i2))} for every iterator \tcode{i1} in the range \range{first1}{last1} @@ -8984,12 +8974,12 @@ \rSec2[transform.reduce]{Transform reduce} \indexlibrary{\idxcode{transform_reduce}}% \begin{itemdecl} -template +template T transform_reduce(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); -template +template T transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, @@ -9006,16 +8996,16 @@ \indexlibrary{\idxcode{transform_reduce}}% \begin{itemdecl} -template +template T transform_reduce(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); -template +template T transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, @@ -9107,11 +9097,11 @@ \indexlibrary{\idxcode{partial_sum}}% \begin{itemdecl} -template +template OutputIterator partial_sum( InputIterator first, InputIterator last, OutputIterator result); -template +template OutputIterator partial_sum( InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); @@ -9121,7 +9111,7 @@ \pnum \requires \tcode{InputIterator}'s value type shall be constructible from the type of \tcode{*first}. -The result of the expression \tcode{acc + *i} or \tcode{binary_op(acc, *i)} shall be +The result of the expression \tcode{std::move(acc) + *i} or \tcode{binary_op(std::move(acc), *i)} shall be implicitly convertible to \tcode{InputIterator}'s value type. \tcode{acc} shall be writable\iref{iterator.requirements.general} to the \tcode{result} output iterator. In the ranges @@ -9137,7 +9127,7 @@ the function creates an accumulator \tcode{acc} whose type is \tcode{InputIterator}'s value type, initializes it with \tcode{*first}, and assigns the result to \tcode{*result}. For every iterator \tcode{i} in \range{first + 1}{last} -in order, \tcode{acc} is then modified by \tcode{acc = acc + *i} or \tcode{acc = binary_op(acc, *i)} +in order, \tcode{acc} is then modified by \tcode{acc = std::move(acc) + *i} or \tcode{acc = binary_op(std::move(acc), *i)} and the result is assigned to \tcode{*(result + (i - first))}. \pnum @@ -9518,20 +9508,20 @@ \indexlibrary{\idxcode{adjacent_difference}}% \begin{itemdecl} -template +template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); -template +template ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); -template +template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); -template +template ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, @@ -9547,8 +9537,8 @@ type shall be \tcode{MoveAssignable} (Table~\ref{tab:moveassignable}) and shall be constructible from the type of \tcode{*first}. \tcode{acc} (defined below) shall be writable\iref{iterator.requirements.general} to the \tcode{result} -output iterator. The result of the expression \tcode{val - acc} or -\tcode{binary_op(val, acc)} shall be writable to the \tcode{result} output iterator. +output iterator. The result of the expression \tcode{val - std::move(acc)} or +\tcode{binary_op(val, std::move(acc))} shall be writable to the \tcode{result} output iterator. \item For the overloads with an \tcode{ExecutionPolicy}, the value type of @@ -9574,7 +9564,7 @@ value type, initializes it with \tcode{*first}, and assigns the result to \tcode{*result}. For every iterator \tcode{i} in \range{first + 1}{last} in order, creates an object \tcode{val} whose type is \tcode{InputIterator}'s value type, initializes it -with \tcode{*i}, computes \tcode{val - acc} or \tcode{binary_op(val, acc)}, assigns the result +with \tcode{*i}, computes \tcode{val - std::move(acc)} or \tcode{binary_op(val, std::move(acc))}, assigns the result to \tcode{*(result + (i - first))}, and move assigns from \tcode{val} to \tcode{acc}. \pnum @@ -9610,7 +9600,7 @@ \indexlibrary{\idxcode{iota}}% \begin{itemdecl} -template +template void iota(ForwardIterator first, ForwardIterator last, T value); \end{itemdecl} @@ -9633,7 +9623,7 @@ \indexlibrary{\idxcode{gcd}}% \begin{itemdecl} -template +template constexpr common_type_t gcd(M m, N n); \end{itemdecl} @@ -9664,7 +9654,7 @@ \indexlibrary{\idxcode{lcm}}% \begin{itemdecl} -template +template constexpr common_type_t lcm(M m, N n); \end{itemdecl} @@ -9696,8 +9686,7 @@ \rSec2[cmath.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cmath}}% -\indexlibrary{\idxhdr{cmath}}% +\indexhdr{cmath}% \indexlibrary{\idxcode{FP_FAST_FMA}}% \indexlibrary{\idxcode{FP_FAST_FMAF}}% \indexlibrary{\idxcode{FP_FAST_FMAL}}% @@ -10435,7 +10424,7 @@ long double sph_legendrel(unsigned l, unsigned m, long double theta); // \ref{sf.cmath.sph_neumann}, spherical Neumann functions; - // spherical Bessel functions of the second kind: + // spherical Bessel functions of the second kind double sph_neumann(unsigned n, double x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x); @@ -10485,10 +10474,8 @@ \rSec2[c.math.abs]{Absolute values} \pnum -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% -\indextext{\idxhdr{cmath}}% -\indexlibrary{\idxhdr{cmath}}% +\indexhdr{cstdlib}% +\indexhdr{cmath}% \begin{note} The headers \tcode{}\iref{cstdlib.syn} and \tcode{}\iref{cmath.syn} diff --git a/source/overloading.tex b/source/overloading.tex index b8e349ac8f..7753a39db7 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -309,7 +309,7 @@ \pnum Two function declarations of the same name refer to the same function if they are in the same scope and have equivalent parameter declarations\iref{over.load} -and equivalent \grammarterm{requires-clause}{s}, if any\iref{temp.constr.decl}. +and equivalent trailing \grammarterm{requires-clause}{s}, if any\iref{dcl.decl}. A function member of a derived class is \textit{not} in the same scope as a function member of the same name in a base class. @@ -647,7 +647,7 @@ In a function call\iref{expr.call} \begin{ncsimplebnf} -postfix-expression \terminal{(} expression-list\opt{} \terminal{)} +postfix-expression \terminal{(} \opt{expression-list} \terminal{)} \end{ncsimplebnf} if the \grammarterm{postfix-expression} denotes a set of overloaded functions and/or @@ -816,7 +816,7 @@ form \begin{ncsimplebnf} -\terminal{operator} conversion-type-id \terminal{(\,)} cv-qualifier ref-qualifier\opt noexcept-specifier\opt attribute-specifier-seq\opt{} \terminal{;} +\terminal{operator} conversion-type-id \terminal{(\,)} cv-qualifier \opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \terminal{;} \end{ncsimplebnf} where @@ -909,7 +909,7 @@ \pnum If no operand of an operator in an expression has a type that is a class or an enumeration, the operator is assumed to be a built-in operator -and interpreted according to \ref{expr}. +and interpreted according to \ref{expr.compound}. \begin{note} Because \tcode{.}, @@ -918,7 +918,7 @@ \tcode{::} cannot be overloaded, these operators are always built-in operators interpreted according to -\ref{expr}. +\ref{expr.compound}. \tcode{?:} cannot be overloaded, but the rules in this subclause are used to determine the conversions to be applied to the second and third operands when they @@ -956,7 +956,7 @@ Table~\ref{tab:over.rel.op.func} (where \tcode{@} denotes one of the operators covered in the specified subclause). However, the operands are sequenced in the order prescribed -for the built-in operator\iref{expr}. +for the built-in operator\iref{expr.compound}. \begin{floattable}{Relationship between operator and function call notation}{tab:over.rel.op.func} {l|m|m|m} @@ -1058,9 +1058,29 @@ For all other operators, no such restrictions apply. \pnum -The set of candidate functions for overload resolution is the +The set of candidate functions for overload resolution +for some operator \tcode{@} +is the union of the member candidates, the non-member candidates, and -the built-in candidates. +the built-in candidates for that operator \tcode{@}. +If that operator is a +relational\iref{expr.rel} or equality\iref{expr.eq} operator +with operands \tcode{x} and \tcode{y}, +then for each member, non-member, or built-in candidate +for the operator \tcode{<=>}: +\begin{itemize} +\item +that operator is added to the set of candidate functions for overload resolution +if \tcode{x <=> y @ 0} is well-formed using that \tcode{operator<=>}; and +\item +a synthesized candidate is added to the candidate set +where the order of the two parameters is reversed +if \tcode{0 @ y <=> x} is well-formed using that \tcode{operator<=>}; +\end{itemize} +where in each case \tcode{operator<=>} candidates +are not considered for the recursive lookup of operator \tcode{@}. + +\pnum The argument list contains all of the operands of the operator. The best function from the set of candidate functions is selected @@ -1081,14 +1101,24 @@ \end{codeblock} \end{example} -% USA _136/_28 L6899 USA core-756/734/682 over.match.oper +\pnum +If an \tcode{operator<=>} candidate +is selected by overload resolution for an operator \tcode{@}, +but \tcode{@} is not \tcode{<=>}, +\tcode{x @ y} +is interpreted as \tcode{0 @ y <=> x} +if the selected candidate is a synthesized candidate +with reversed order of parameters, +or \tcode{x <=> y @ 0} otherwise, +using the selected \tcode{operator<=>} candidate. + \pnum If a built-in candidate is selected by overload resolution, the operands of class type are converted to the types of the corresponding parameters of the selected operation function, except that the second standard conversion sequence of a user-defined conversion sequence\iref{over.ics.user} is not applied. Then the operator is treated as the corresponding -built-in operator and interpreted according to \ref{expr}. +built-in operator and interpreted according to \ref{expr.compound}. \begin{example} \begin{codeblock} struct X { @@ -1135,7 +1165,7 @@ \tcode{->}, and there are no viable functions, then the operator is assumed to be the built-in operator and interpreted according to -\ref{expr}. +\ref{expr.compound}. \pnum \begin{note} @@ -1359,7 +1389,7 @@ \pnum When objects of non-aggregate class type \tcode{T} are list-initialized such that \ref{dcl.init.list} specifies that overload resolution -is performed according to the rules in this section, overload resolution selects the +is performed according to the rules in this subclause, overload resolution selects the constructor in two phases: \begin{itemize} @@ -1652,7 +1682,7 @@ \item the context is an initialization by conversion function for direct reference binding\iref{over.match.ref} of a reference to function type, the -return type of \tcode{F1} is the same kind of reference (i.e. lvalue or rvalue) +return type of \tcode{F1} is the same kind of reference (lvalue or rvalue) as the reference being initialized, and the return type of \tcode{F2} is not \begin{example} \begin{codeblock} @@ -1719,6 +1749,39 @@ \end{example} or, if not that, +\item +\tcode{F1} is an operator function +for a relational\iref{expr.rel} or equality\iref{expr.eq} operator +and \tcode{F2} is an operator function +for a three-way comparison operator\iref{expr.spaceship} +\begin{example} +\begin{codeblock} +struct S { + auto operator<=>(const S&, const S&) = default; // \#1 + bool operator<(const S&, const S&); // \#2 +}; +bool b = S() < S(); // calls \#2 +\end{codeblock} +\end{example} +or, if not that, + +\item +\tcode{F1} and \tcode{F2} are operator functions +for \tcode{operator<=>} and +\tcode{F2} is a synthesized candidate +with reversed order of parameters +and \tcode{F1} is not +\begin{example} +\begin{codeblock} +struct S { + std::weak_ordering operator<=>(const S&, int); // \#1 + std::weak_ordering operator<=>(int, const S&); // \#2 +}; +bool b = 1 < S(); // calls \#2 +\end{codeblock} +\end{example} +or, if not that + \item \tcode{F1} is generated from a \grammarterm{deduction-guide}\iref{over.match.class.deduct} @@ -2083,7 +2146,7 @@ Floating-point conversions & & & \ref{conv.double} \\ \cline{1-1}\cline{4-4} Floating-integral conversions & & & \ref{conv.fpint} \\ \cline{1-1}\cline{4-4} Pointer conversions & \rb{Conversion} & \rb{Conversion} & \ref{conv.ptr} \\ \cline{1-1}\cline{4-4} -Pointer to member conversions & & & \ref{conv.mem} \\ \cline{1-1}\cline{4-4} +Pointer-to-member conversions & & & \ref{conv.mem} \\ \cline{1-1}\cline{4-4} Boolean conversions & & & \ref{conv.bool} \\ \end{floattable} @@ -2373,7 +2436,7 @@ \pnum Otherwise, if the parameter is a reference, see~\ref{over.ics.ref}. \begin{note} -The rules in this section will apply for initializing the underlying temporary +The rules in this subclause will apply for initializing the underlying temporary for the reference. \end{note} \begin{example} \begin{codeblock} struct A { @@ -2874,7 +2937,7 @@ match targets of function pointer type or reference to function type. Non-static member functions match targets of -pointer to member function type. +pointer-to-member-function type. If a non-static member function is selected, the reference to the overloaded function name is required to have the form of a pointer to member as described in~\ref{expr.unary.op}. @@ -3007,14 +3070,12 @@ \begin{bnfkeywordtab} \nontermdef{operator} \textnormal{one of}\br -\>new\>delete\>new[]\>delete[]\br -\>+\>-\>*\>/\>\%\>\caret\>\&\>|\>\~\br -\>!\>=\><\>>\>+=\>-=\>*=\>/=\>\%=\br -\>\caret=\>\&=\>|=\><<\>>>\>>>=\><<=\>={=}\>!=\br -\><=\>>=\>\&\&\>|{|}\>++\>-{-}\>,\>->*\>->\br -\>(\,)\>[\,] +\>new\>delete\>new[]\>delete[]\>(\,)\>[\,]\>->\>->*\>\~\br +\>!\>+\>-\>*\>/\>\%\>\caret\>\&\>|\br +\>=\>+=\>-=\>*=\>/=\>\%=\>\caret=\>\&=\>|=\br +\>={=}\>!=\><\>>\><=\>>=\><=>\>\&\&\>|{|}\br +\><<\>>>\><<=\>>>=\>++\>-{-}\>,\br \end{bnfkeywordtab} - \begin{note} The last two operators are function call\iref{expr.call} and subscripting\iref{expr.sub}. @@ -3248,7 +3309,7 @@ It implements the function call syntax \begin{ncsimplebnf} -postfix-expression \terminal{(} expression-list\opt{} \terminal{)} +postfix-expression \terminal{(} \opt{expression-list} \terminal{)} \end{ncsimplebnf} where the @@ -3321,7 +3382,7 @@ uses \tcode{->}. \begin{ncsimplebnf} -postfix-expression \terminal{->} \terminal{template\opt} id-expression\\ +postfix-expression \terminal{->} \terminal{\opt{template}} id-expression\\ postfix-expression \terminal{->} pseudo-destructor-name \end{ncsimplebnf} @@ -3507,7 +3568,7 @@ \pnum The candidate operator functions that represent the built-in operators -defined in \ref{expr} are specified in this subclause. +defined in \ref{expr.compound} are specified in this subclause. These candidate functions participate in the operator overload resolution process as described in~\ref{over.match.oper} and are used for no other purpose. @@ -3525,7 +3586,7 @@ As described in~\ref{over.match.oper}, after a built-in operator is selected by overload resolution the expression is subject to the requirements for -the built-in operator given in \ref{expr}, and therefore to any +the built-in operator given in \ref{expr.compound}, and therefore to any additional semantic constraints given there. If there is a user-written candidate with the same name and parameter types as a built-in @@ -3555,7 +3616,7 @@ \end{note} \pnum -In the remainder of this section, \cvqual{vq} represents either +In the remainder of this subclause, \cvqual{vq} represents either \tcode{volatile} or no cv-qualifier. \pnum @@ -3693,11 +3754,28 @@ where \tcode{\placeholder{LR}} -is the result of the usual arithmetic conversions between types +is the result of the usual arithmetic conversions\iref{expr.arith.conv} between types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}. +\pnum +For every integral type \tcode{\placeholder{T}} +there exists a candidate operator function of the form + +\begin{codeblock} +std::strong_ordering operator<=>(@\placeholder{T}@, @\placeholder{T}@); +\end{codeblock} + +\pnum +For every pair of floating-point types +\tcode{\placeholder{L}} and \tcode{\placeholder{R}}, +there exists a candidate operator function of the form + +\begin{codeblock} +std::partial_ordering operator<=>(@\placeholder{L}@, @\placeholder{R}@); +\end{codeblock} + \pnum For every cv-qualified or cv-unqualified object type \tcode{\placeholder{T}} @@ -3734,15 +3812,20 @@ bool operator>=(@\placeholder{T}@, @\placeholder{T}@); bool operator==(@\placeholder{T}@, @\placeholder{T}@); bool operator!=(@\placeholder{T}@, @\placeholder{T}@); +@\placeholdernc{R}@ operator<=>(@\placeholder{T}@, @\placeholder{T}@); \end{codeblock} +where \tcode{\placeholder{R}} is the result type specified in \ref{expr.spaceship}. + \pnum -For every pointer to member type \tcode{\placeholder{T}} or type \tcode{std::nullptr_t} there -exist candidate operator functions of the form +For every \tcode{\placeholder{T}}, where \tcode{\placeholder{T}} +is a pointer-to-member type or \tcode{std::nullptr_t}, +there exist candidate operator functions of the form \begin{codeblock} -bool operator==(@\placeholder{T}@, @\placeholder{T}@); -bool operator!=(@\placeholder{T}@, @\placeholder{T}@); +bool operator==(@\placeholder{T}@, @\placeholder{T}@); +bool operator!=(@\placeholder{T}@, @\placeholder{T}@); +std::strong_equality operator<=>(@\placeholder{T}@, @\placeholder{T}@); \end{codeblock} \pnum @@ -3763,7 +3846,7 @@ where \tcode{\placeholder{LR}} -is the result of the usual arithmetic conversions between types +is the result of the usual arithmetic conversions\iref{expr.arith.conv} between types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}. @@ -3804,7 +3887,7 @@ \cvqual{vq}), where \tcode{\placeholder{T}} -is an enumeration or pointer to member type, +is an enumeration or pointer-to-member type, there exist candidate operator functions of the form \begin{codeblock} @@ -3868,7 +3951,7 @@ where \tcode{\placeholder{LR}} -is the result of the usual arithmetic conversions between types +is the result of the usual arithmetic conversions\iref{expr.arith.conv} between types \tcode{\placeholder{L}} and \tcode{\placeholder{R}}. diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 81bf2b3b17..5418ba61f5 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -30,7 +30,7 @@ \begin{bnf} \nontermdef{preprocessing-file}\br - group\opt + \opt{group} \end{bnf} \begin{bnf} @@ -51,26 +51,26 @@ \nontermdef{control-line}\br \>\terminal{\# include}\>\>pp-tokens new-line\br \>\terminal{\# define}\>\>identifier replacement-list new-line\br -\>\terminal{\# define}\>\>identifier lparen identifier-list\opt{} \terminal{)} replacement-list new-line\br +\>\terminal{\# define}\>\>identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br \>\terminal{\# define}\>\>identifier lparen \terminal{... )} replacement-list new-line\br \>\terminal{\# define}\>\>identifier lparen identifier-list \terminal{, ... )} replacement-list new-line\br \>\terminal{\# undef}\>\>identifier new-line\br \>\terminal{\# line}\>\>pp-tokens new-line\br -\>\terminal{\# error}\>\>pp-tokens\opt new-line\br -\>\terminal{\# pragma}\>\>pp-tokens\opt new-line\br +\>\terminal{\# error}\>\>\opt{pp-tokens} new-line\br +\>\terminal{\# pragma}\>\>\opt{pp-tokens} new-line\br \>\terminal{\# }new-line \end{bnftab} \begin{bnf} \nontermdef{if-section}\br - if-group elif-groups\opt else-group\opt endif-line + if-group \opt{elif-groups} \opt{else-group} endif-line \end{bnf} \begin{bnftab} \nontermdef{if-group}\br -\>\terminal{\# if}\>\>constant-expression new-line group\opt\br -\>\terminal{\# ifdef}\>\>identifier new-line group\opt\br -\>\terminal{\# ifndef}\>\>identifier new-line group\opt +\>\terminal{\# if}\>\>constant-expression new-line \opt{group}\br +\>\terminal{\# ifdef}\>\>identifier new-line \opt{group}\br +\>\terminal{\# ifndef}\>\>identifier new-line \opt{group} \end{bnftab} \begin{bnf} @@ -81,12 +81,12 @@ \begin{bnftab} \nontermdef{elif-group}\br -\>\terminal{\# elif}\>\>constant-expression new-line group\opt +\>\terminal{\# elif}\>\>constant-expression new-line \opt{group} \end{bnftab} \begin{bnftab} \nontermdef{else-group}\br -\>\terminal{\# else}\>\>new-line group\opt +\>\terminal{\# else}\>\>new-line \opt{group} \end{bnftab} \begin{bnftab} @@ -96,7 +96,7 @@ \begin{bnf} \nontermdef{text-line}\br - pp-tokens\opt new-line + \opt{pp-tokens} new-line \end{bnf} \begin{bnf} @@ -117,7 +117,7 @@ \begin{bnf} \nontermdef{replacement-list}\br - pp-tokens\opt + \opt{pp-tokens} \end{bnf} \begin{bnf} @@ -261,7 +261,7 @@ the \tcode{defined} conditional inclusion operator, shall treat \xname{has_include} as if it were the name of a defined macro. The identifier \xname{has_include} shall not appear -in any context not mentioned in this section. +in any context not mentioned in this subclause. \pnum Each preprocessing token that remains (in the list of preprocessing tokens that @@ -274,9 +274,9 @@ \begin{ncbnftab} \indextext{\idxcode{\#if}}% -\terminal{\# if}\>\>constant-expression new-line group\opt\br +\terminal{\# if}\>\>constant-expression new-line \opt{group}\br \indextext{\idxcode{\#elif}}% -\terminal{\# elif}\>\>constant-expression new-line group\opt +\terminal{\# elif}\>\>constant-expression new-line \opt{group} \end{ncbnftab} check whether the controlling constant expression evaluates to nonzero. @@ -369,9 +369,9 @@ Preprocessing directives of the forms \begin{ncbnftab} -\terminal{\# ifdef}\>\>identifier new-line group\opt\br +\terminal{\# ifdef}\>\>identifier new-line \opt{group}\br \indextext{\idxcode{\#ifdef}}% -\terminal{\# ifndef}\>\>identifier new-line group\opt +\terminal{\# ifndef}\>\>identifier new-line \opt{group} \indextext{\idxcode{\#ifndef}}% \end{ncbnftab} @@ -688,7 +688,7 @@ \pnum A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# define} identifier lparen identifier-list\opt{} \terminal{)} replacement-list new-line\br +\terminal{\# define} identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br \terminal{\# define} identifier lparen \terminal{...} \terminal{)} replacement-list new-line\br \terminal{\# define} identifier lparen identifier-list \terminal{, ...} \terminal{)} replacement-list new-line \end{ncsimplebnf} @@ -1213,7 +1213,7 @@ A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# line} digit-sequence \terminal{"} s-char-sequence\opt{} \terminal{"} new-line +\terminal{\# line} digit-sequence \terminal{"} \opt{s-char-sequence} \terminal{"} new-line \end{ncsimplebnf} sets the presumed line number similarly and changes the @@ -1246,7 +1246,7 @@ A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# error} pp-tokens\opt new-line +\terminal{\# error} \opt{pp-tokens} new-line \end{ncsimplebnf} causes the implementation to produce @@ -1261,7 +1261,7 @@ A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# pragma} pp-tokens\opt new-line +\terminal{\# pragma} \opt{pp-tokens} new-line \end{ncsimplebnf} causes the implementation to behave diff --git a/source/regex.tex b/source/regex.tex index 3320472cb6..0a7126aab5 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -6,7 +6,7 @@ \pnum -This Clause describes components that \Cpp programs may use to +This Clause describes components that \Cpp{} programs may use to perform operations involving regular expression matching and searching. @@ -254,7 +254,7 @@ \rSec1[re.syn]{Header \tcode{} synopsis} -\indexlibrary{\idxhdr{regex}}% +\indexhdr{regex}% \indexlibrary{\idxcode{basic_regex}}% \indexlibrary{\idxcode{regex}}% \indexlibrary{\idxcode{wregex}}% @@ -273,20 +273,20 @@ class regex_error; // \ref{re.traits}, class template \tcode{regex_traits} - template struct regex_traits; + template struct regex_traits; // \ref{re.regex}, class template \tcode{basic_regex} - template > class basic_regex; + template> class basic_regex; using regex = basic_regex; using wregex = basic_regex; // \ref{re.regex.swap}, \tcode{basic_regex} swap - template + template void swap(basic_regex& e1, basic_regex& e2); // \ref{re.submatch}, class template \tcode{sub_match} - template + template class sub_match; using csub_match = sub_match; @@ -295,152 +295,152 @@ using wssub_match = sub_match; // \ref{re.submatch.op}, \tcode{sub_match} non-member operators - template + template bool operator==(const sub_match& lhs, const sub_match& rhs); - template + template bool operator!=(const sub_match& lhs, const sub_match& rhs); - template + template bool operator<(const sub_match& lhs, const sub_match& rhs); - template + template bool operator<=(const sub_match& lhs, const sub_match& rhs); - template + template bool operator>=(const sub_match& lhs, const sub_match& rhs); - template + template bool operator>(const sub_match& lhs, const sub_match& rhs); - template + template bool operator==( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator!=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator<( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator>( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator>=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator<=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); - template + template bool operator==( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator!=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator<( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator>( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator>=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator<=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); - template + template bool operator==(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator!=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator<(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator>(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator>=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator<=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); - template + template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator!=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator<(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator>(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator>=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator<=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); - template + template bool operator==(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator!=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator<(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator>(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator>=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator<=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); - template + template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template bool operator!=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template bool operator<(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template bool operator>(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template bool operator>=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template bool operator<=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); - template + template basic_ostream& operator<<(basic_ostream& os, const sub_match& m); // \ref{re.results}, class template \tcode{match_results} - template >> + template>> class match_results; using cmatch = match_results; @@ -449,83 +449,83 @@ using wsmatch = match_results; // \tcode{match_results} comparisons - template + template bool operator==(const match_results& m1, const match_results& m2); - template + template bool operator!=(const match_results& m1, const match_results& m2); // \ref{re.results.swap}, \tcode{match_results} swap - template + template void swap(match_results& m1, match_results& m2); // \ref{re.alg.match}, function template \tcode{regex_match} - template + template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_match(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_match(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_match(const basic_string&&, match_results::const_iterator, Allocator>&, const basic_regex&, regex_constants::match_flag_type = regex_constants::match_default) = delete; - template + template bool regex_match(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_match(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); // \ref{re.alg.search}, function template \tcode{regex_search} - template + template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(const basic_string& s, match_results::const_iterator, Allocator>& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template bool regex_search(const basic_string&&, match_results::const_iterator, Allocator>&, @@ -534,7 +534,7 @@ = regex_constants::match_default) = delete; // \ref{re.alg.replace}, function template \tcode{regex_replace} - template OutputIterator regex_replace(OutputIterator out, @@ -542,32 +542,32 @@ const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template basic_string regex_replace(const basic_string& s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template basic_string regex_replace(const basic_string& s, const basic_regex& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template basic_string regex_replace(const charT* s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - template + template basic_string regex_replace(const charT* s, const basic_regex& e, @@ -575,7 +575,7 @@ regex_constants::match_flag_type flags = regex_constants::match_default); // \ref{re.regiter}, class template \tcode{regex_iterator} - template ::value_type, class traits = regex_traits> class regex_iterator; @@ -586,7 +586,7 @@ using wsregex_iterator = regex_iterator; // \ref{re.tokiter}, class template \tcode{regex_token_iterator} - template ::value_type, class traits = regex_traits> class regex_token_iterator; @@ -597,7 +597,7 @@ using wsregex_token_iterator = regex_token_iterator; namespace pmr { - template + template using match_results = std::match_results>>; @@ -1016,7 +1016,7 @@ \indexlibrary{\idxcode{regex_traits}}% \begin{codeblock} namespace std { - template + template struct regex_traits { using char_type = charT; using string_type = basic_string; @@ -1027,15 +1027,15 @@ static size_t length(const char_type* p); charT translate(charT c) const; charT translate_nocase(charT c) const; - template + template string_type transform(ForwardIterator first, ForwardIterator last) const; - template + template string_type transform_primary( ForwardIterator first, ForwardIterator last) const; - template + template string_type lookup_collatename( ForwardIterator first, ForwardIterator last) const; - template + template char_class_type lookup_classname( ForwardIterator first, ForwardIterator last, bool icase = false) const; bool isctype(charT c, char_class_type f) const; @@ -1095,7 +1095,7 @@ \indexlibrarymember{regex_traits}{transform}% \begin{itemdecl} -template +template string_type transform(ForwardIterator first, ForwardIterator last) const; \end{itemdecl} @@ -1111,7 +1111,7 @@ \indexlibrarymember{regex_traits}{transform_primary}% \begin{itemdecl} -template +template string_type transform_primary(ForwardIterator first, ForwardIterator last) const; \end{itemdecl} @@ -1130,7 +1130,7 @@ \indexlibrarymember{regex_traits}{lookup_collatename}% \begin{itemdecl} -template +template string_type lookup_collatename(ForwardIterator first, ForwardIterator last) const; \end{itemdecl} @@ -1144,7 +1144,7 @@ \indexlibrarymember{regex_traits}{lookup_classname}% \begin{itemdecl} -template +template char_class_type lookup_classname( ForwardIterator first, ForwardIterator last, bool icase = false) const; \end{itemdecl} @@ -1326,10 +1326,10 @@ \indexlibrary{\idxcode{basic_regex}}% \begin{codeblock} namespace std { - template > + template> class basic_regex { public: - // types: + // types using value_type = charT; using traits_type = traits; using string_type = typename traits::string_type; @@ -1366,10 +1366,10 @@ basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript); basic_regex(const basic_regex&); basic_regex(basic_regex&&) noexcept; - template + template explicit basic_regex(const basic_string& p, flag_type f = regex_constants::ECMAScript); - template + template basic_regex(ForwardIterator first, ForwardIterator last, flag_type f = regex_constants::ECMAScript); basic_regex(initializer_list, flag_type = regex_constants::ECMAScript); @@ -1380,7 +1380,7 @@ basic_regex& operator=(basic_regex&&) noexcept; basic_regex& operator=(const charT* ptr); basic_regex& operator=(initializer_list il); - template + template basic_regex& operator=(const basic_string& p); // \ref{re.regex.assign}, assign @@ -1388,10 +1388,10 @@ basic_regex& assign(basic_regex&& that) noexcept; basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript); basic_regex& assign(const charT* p, size_t len, flag_type f); - template + template basic_regex& assign(const basic_string& s, flag_type f = regex_constants::ECMAScript); - template + template basic_regex& assign(InputIterator first, InputIterator last, flag_type f = regex_constants::ECMAScript); basic_regex& assign(initializer_list, @@ -1532,7 +1532,7 @@ \indexlibrary{\idxcode{basic_regex}!constructor}% \begin{itemdecl} -template +template explicit basic_regex(const basic_string& s, flag_type f = regex_constants::ECMAScript); \end{itemdecl} @@ -1555,7 +1555,7 @@ \indexlibrary{\idxcode{basic_regex}!constructor}% \begin{itemdecl} -template +template basic_regex(ForwardIterator first, ForwardIterator last, flag_type f = regex_constants::ECMAScript); \end{itemdecl} @@ -1643,7 +1643,7 @@ \indexlibrarymember{basic_regex}{operator=}% \begin{itemdecl} -template +template basic_regex& operator=(const basic_string& p); \end{itemdecl} @@ -1659,10 +1659,7 @@ \begin{itemdescr} \pnum -\effects Equivalent to \tcode{*this = that}. - -\pnum -\returns \tcode{*this}. +\effects Equivalent to: \tcode{return *this = that;} \end{itemdescr} \indexlibrarymember{basic_regex}{assign}% @@ -1672,10 +1669,7 @@ \begin{itemdescr} \pnum -\effects Equivalent to \tcode{*this = std::move(that)}. - -\pnum -\returns \tcode{*this}. +\effects Equivalent to: \tcode{return *this = std::move(that);} \end{itemdescr} \indexlibrarymember{basic_regex}{assign}% @@ -1700,7 +1694,7 @@ \indexlibrarymember{basic_regex}{assign}% \begin{itemdecl} -template +template basic_regex& assign(const basic_string& s, flag_type f = regex_constants::ECMAScript); \end{itemdecl} @@ -1726,7 +1720,7 @@ \indexlibrarymember{basic_regex}{assign}% \begin{itemdecl} -template +template basic_regex& assign(InputIterator first, InputIterator last, flag_type f = regex_constants::ECMAScript); \end{itemdecl} @@ -1830,7 +1824,7 @@ \rSec3[re.regex.nmswap]{\tcode{basic_regex} non-member swap} \indexlibrarymember{basic_regex}{swap}% \begin{itemdecl} -template +template void swap(basic_regex& lhs, basic_regex& rhs); \end{itemdecl} @@ -1846,7 +1840,7 @@ \begin{codeblock} namespace std { - template + template class sub_match : public pair { public: using value_type = @@ -1943,7 +1937,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -1953,7 +1947,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -1963,7 +1957,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -1973,7 +1967,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -1983,7 +1977,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -1993,7 +1987,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>(const sub_match& lhs, const sub_match& rhs); \end{itemdecl} @@ -2003,7 +1997,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2019,7 +2013,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2031,7 +2025,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2047,7 +2041,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2059,7 +2053,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2071,7 +2065,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=( const basic_string::value_type, ST, SA>& lhs, const sub_match& rhs); @@ -2083,7 +2077,7 @@ \indexlibrarymember{operator==}{sub_match}% \begin{itemdecl} -template +template bool operator==( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2100,7 +2094,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{sub_match}}% \indexlibrary{\idxcode{sub_match}!\idxcode{operator"!=}}% \begin{itemdecl} -template +template bool operator!=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2113,7 +2107,7 @@ \indexlibrary{\idxcode{operator>}!\idxcode{sub_match}}% \indexlibrary{\idxcode{sub_match}!\idxcode{operator<}}% \begin{itemdecl} -template +template bool operator<( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2129,7 +2123,7 @@ \indexlibrarymember{operator>}{sub_match}% \begin{itemdecl} -template +template bool operator>( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2141,7 +2135,7 @@ \indexlibrarymember{operator>=}{sub_match}% \begin{itemdecl} -template +template bool operator>=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2153,7 +2147,7 @@ \indexlibrarymember{operator<=}{sub_match}% \begin{itemdecl} -template +template bool operator<=( const sub_match& lhs, const basic_string::value_type, ST, SA>& rhs); @@ -2165,7 +2159,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2176,7 +2170,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2187,7 +2181,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2198,7 +2192,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2209,7 +2203,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2220,7 +2214,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=(const typename iterator_traits::value_type* lhs, const sub_match& rhs); \end{itemdecl} @@ -2231,7 +2225,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2242,7 +2236,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2253,7 +2247,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2264,7 +2258,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2275,7 +2269,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2286,7 +2280,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=(const sub_match& lhs, const typename iterator_traits::value_type* rhs); \end{itemdecl} @@ -2298,7 +2292,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2310,7 +2304,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2322,7 +2316,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2334,7 +2328,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2346,7 +2340,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2358,7 +2352,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=(const typename iterator_traits::value_type& lhs, const sub_match& rhs); \end{itemdecl} @@ -2370,7 +2364,7 @@ \indexlibrarymember{sub_match}{operator==}% \begin{itemdecl} -template +template bool operator==(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2382,7 +2376,7 @@ \indexlibrarymember{sub_match}{operator"!=}% \begin{itemdecl} -template +template bool operator!=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2394,7 +2388,7 @@ \indexlibrarymember{sub_match}{operator<}% \begin{itemdecl} -template +template bool operator<(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2406,7 +2400,7 @@ \indexlibrarymember{sub_match}{operator>}% \begin{itemdecl} -template +template bool operator>(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2418,7 +2412,7 @@ \indexlibrarymember{sub_match}{operator>=}% \begin{itemdecl} -template +template bool operator>=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2430,7 +2424,7 @@ \indexlibrarymember{sub_match}{operator<=}% \begin{itemdecl} -template +template bool operator<=(const sub_match& lhs, const typename iterator_traits::value_type& rhs); \end{itemdecl} @@ -2443,7 +2437,7 @@ \indexlibrary{\idxcode{basic_ostream}}% \indexlibrarymember{sub_match}{operator<<}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream& os, const sub_match& m); \end{itemdecl} @@ -2497,8 +2491,8 @@ \begin{codeblock} namespace std { - template >> + template>> class match_results { public: using value_type = sub_match; @@ -2528,7 +2522,7 @@ // \ref{re.results.size}, size size_type size() const; size_type max_size() const; - bool empty() const; + [[nodiscard]] bool empty() const; // \ref{re.results.acc}, element access difference_type length(size_type sub = 0) const; @@ -2544,17 +2538,17 @@ const_iterator cend() const; // \ref{re.results.form}, format - template + template OutputIter format(OutputIter out, const char_type* fmt_first, const char_type* fmt_last, regex_constants::match_flag_type flags = regex_constants::format_default) const; - template + template OutputIter format(OutputIter out, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const; - template + template basic_string format(const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const; @@ -2697,7 +2691,7 @@ \indexlibrarymember{match_results}{empty}% \begin{itemdecl} -bool empty() const; +[[nodiscard]] bool empty() const; \end{itemdecl} \begin{itemdescr} @@ -2820,7 +2814,7 @@ \indexlibrarymember{match_results}{format}% \begin{itemdecl} -template +template OutputIter format( OutputIter out, const char_type* fmt_first, const char_type* fmt_last, @@ -2846,7 +2840,7 @@ \indexlibrarymember{match_results}{format}% \begin{itemdecl} -template +template OutputIter format( OutputIter out, const basic_string& fmt, @@ -2863,7 +2857,7 @@ \indexlibrarymember{match_results}{format}% \begin{itemdecl} -template +template basic_string format( const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const; @@ -2940,7 +2934,7 @@ \indexlibrarymember{match_results}{swap}% \begin{itemdecl} -template +template void swap(match_results& m1, match_results& m2); \end{itemdecl} @@ -2951,7 +2945,7 @@ \indexlibrarymember{operator==}{match_results}% \begin{itemdecl} -template +template bool operator==(const match_results& m1, const match_results& m2); \end{itemdecl} @@ -2986,7 +2980,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{match_results}}% \indexlibrary{\idxcode{match_results}!\idxcode{operator"!=}}% \begin{itemdecl} -template +template bool operator!=(const match_results& m1, const match_results& m2); \end{itemdecl} @@ -3008,7 +3002,7 @@ \rSec2[re.alg.match]{\tcode{regex_match}} \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, @@ -3118,7 +3112,7 @@ \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3134,7 +3128,7 @@ \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(const charT* str, match_results& m, const basic_regex& e, @@ -3148,7 +3142,7 @@ \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(const basic_string& s, match_results::const_iterator, Allocator>& m, @@ -3163,7 +3157,7 @@ \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3176,7 +3170,7 @@ \indexlibrary{\idxcode{regex_match}}% \begin{itemdecl} -template +template bool regex_match(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3191,7 +3185,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results& m, const basic_regex& e, @@ -3286,7 +3280,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(const charT* str, match_results& m, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3299,7 +3293,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(const basic_string& s, match_results::const_iterator, Allocator>& m, @@ -3314,7 +3308,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3329,7 +3323,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(const charT* str, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3342,7 +3336,7 @@ \indexlibrary{\idxcode{regex_search}}% \begin{itemdecl} -template +template bool regex_search(const basic_string& s, const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); @@ -3356,7 +3350,7 @@ \indexlibrary{\idxcode{regex_replace}}% \begin{itemdecl} -template OutputIterator regex_replace(OutputIterator out, @@ -3364,7 +3358,7 @@ const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); -template +template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, @@ -3425,13 +3419,13 @@ \indexlibrary{\idxcode{regex_replace}}% \begin{itemdecl} -template +template basic_string regex_replace(const basic_string& s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); -template +template basic_string regex_replace(const basic_string& s, const basic_regex& e, @@ -3452,13 +3446,13 @@ \indexlibrary{\idxcode{regex_replace}}% \begin{itemdecl} -template +template basic_string regex_replace(const charT* s, const basic_regex& e, const basic_string& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); -template +template basic_string regex_replace(const charT* s, const basic_regex& e, @@ -3509,7 +3503,7 @@ \begin{codeblock} namespace std { - template ::value_type, class traits = regex_traits> class regex_iterator { @@ -3770,7 +3764,7 @@ \begin{codeblock} namespace std { - template ::value_type, class traits = regex_traits> class regex_token_iterator { @@ -3798,7 +3792,7 @@ initializer_list submatches, regex_constants::match_flag_type m = regex_constants::match_default); - template + template regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, const int (&submatches)[N], @@ -3819,7 +3813,7 @@ initializer_list submatches, regex_constants::match_flag_type m = regex_constants::match_default) = delete; - template + template regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type&& re, const int (&submatches)[N], @@ -3895,7 +3889,7 @@ initializer_list submatches, regex_constants::match_flag_type m = regex_constants::match_default); -template +template regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, const int (&submatches)[N], @@ -4039,7 +4033,7 @@ default-constructed instance of their \tcode{traits} template parameter, henceforth referred to as \tcode{traits_inst}. This \tcode{traits_inst} object is used to support localization of the regular expression; \tcode{basic_regex} member functions shall not call -any locale dependent C or \Cpp API, including the formatted string input functions. +any locale dependent C or \Cpp{} API, including the formatted string input functions. Instead they shall call the appropriate traits member function to achieve the required effect. \pnum diff --git a/source/special.tex b/source/special.tex index de6f9f6c47..c068719d68 100644 --- a/source/special.tex +++ b/source/special.tex @@ -4,7 +4,7 @@ \gramSec[gram.special]{Special member functions} \indextext{\idxcode{X(X\&)}|see{constructor, copy}}% -\indextext{~@\tcode{\tilde}|see{destructor}}% +\indextext{~@\tcode{\~}|see{destructor}}% \indextext{assignment!copy|see{assignment operator, copy}}% \indextext{assignment!move|see{assignment operator, move}}% \indextext{implicitly-declared default constructor|see{constructor, default}} @@ -22,7 +22,9 @@ \term{special member functions}. \begin{note} The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. -The implementation will implicitly define them if they are odr-used\iref{basic.def.odr}. +The implementation will implicitly define them +if they are odr-used\iref{basic.def.odr} or +needed for constant evaluation\iref{expr.const}. See~\ref{class.ctor}, \ref{class.dtor} and~\ref{class.copy}. \end{note} An implicitly-declared special member function is declared at the closing \tcode{\}} of the \grammarterm{class-specifier}. @@ -57,8 +59,7 @@ \indextext{access control!member function and}% Special member functions obey the usual access rules\iref{class.access}. \begin{example} -Declaring a constructor -\tcode{protected} +Declaring a constructor protected ensures that only derived classes and friends can create objects using it. \end{example} @@ -77,7 +78,7 @@ function declarator\iref{dcl.fct} of the form \begin{ncbnf} -ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} noexcept-specifier\opt attribute-specifier-seq\opt +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{ncbnf} where the \grammarterm{ptr-declarator} consists solely of an @@ -168,9 +169,7 @@ a non-explicit constructor having no parameters is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared default constructor is an -\tcode{inline} -\tcode{public} -member of its class. +inline public member of its class. \pnum A defaulted default constructor for class \tcode{X} is defined as deleted if: @@ -240,8 +239,9 @@ is \defnx{implicitly defined}{constructor!implicitly defined} when it is odr-used\iref{basic.def.odr} -to create an object of its class type\iref{intro.object} -or when it is explicitly defaulted after its first declaration. +to create an object of its class type\iref{intro.object}, +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no @@ -386,7 +386,7 @@ \end{note} \end{itemize} Even when the creation of the temporary object is -unevaluated\iref{expr}, +unevaluated\iref{expr.prop}, all the semantic restrictions shall be respected as if the temporary object had been created and later destroyed. \begin{note} @@ -416,7 +416,7 @@ \item for certain unevaluated operands~(\ref{expr.typeid}, \ref{expr.sizeof}), and \item -when a prvalue appears as a discarded-value expression\iref{expr}. +when a prvalue appears as a discarded-value expression\iref{expr.prop}. \end{itemize} \end{note} \begin{example} Consider the following code: @@ -548,10 +548,13 @@ where the left operand is one of these expressions and the right operand is a pointer to data member of non-reference type, \item - a \tcode{const_cast}\iref{expr.const.cast}, - \tcode{static_cast}\iref{expr.static.cast}, - \tcode{dynamic_cast}\iref{expr.dynamic.cast}, or - \tcode{reinterpret_cast}\iref{expr.reinterpret.cast} + a + \begin{itemize} + \item \tcode{const_cast}\iref{expr.const.cast}, + \item \tcode{static_cast}\iref{expr.static.cast}, + \item \tcode{dynamic_cast}\iref{expr.dynamic.cast}, or + \item \tcode{reinterpret_cast}\iref{expr.reinterpret.cast} + \end{itemize} converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a glvalue that refers @@ -880,12 +883,12 @@ \begin{bnf} \nontermdef{conversion-type-id}\br - type-specifier-seq conversion-declarator\opt + type-specifier-seq \opt{conversion-declarator} \end{bnf} \begin{bnf} \nontermdef{conversion-declarator}\br - ptr-operator conversion-declarator\opt + ptr-operator \opt{conversion-declarator} \end{bnf} specifies a conversion from @@ -1009,7 +1012,7 @@ function declarator\iref{dcl.fct} of the form \begin{ncbnf} -ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} noexcept-specifier\opt attribute-specifier-seq\opt +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{ncbnf} where the \grammarterm{ptr-declarator} consists solely of an @@ -1078,9 +1081,7 @@ destructor, a destructor is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared destructor is an -\tcode{inline} -\tcode{public} -member of its class. +inline public member of its class. \pnum A defaulted destructor for a class @@ -1485,9 +1486,7 @@ For the call on line ``// 1'' above, if \tcode{B::operator delete()} -had been -\tcode{private}, -the delete expression would have been ill-formed. +had been private, the delete expression would have been ill-formed. \end{example} \pnum @@ -1659,13 +1658,13 @@ \begin{bnf} \nontermdef{mem-initializer-list}\br - mem-initializer \terminal{...}\opt\br - mem-initializer-list \terminal{,} mem-initializer \terminal{...}\opt + mem-initializer \opt{\terminal{...}}\br + mem-initializer-list \terminal{,} mem-initializer \opt{\terminal{...}} \end{bnf} \begin{bnf} \nontermdef{mem-initializer}\br - mem-initializer-id \terminal{(} expression-list\opt{} \terminal{)}\br + mem-initializer-id \terminal{(} \opt{expression-list} \terminal{)}\br mem-initializer-id braced-init-list \end{bnf} @@ -1796,7 +1795,7 @@ \begin{note} The initialization performed by each \grammarterm{mem-initializer} -constitutes a full-expression\iref{intro.execution}. +constitutes a full-expres\-sion\iref{intro.execution}. Any expression in a \grammarterm{mem-initializer} @@ -2680,15 +2679,10 @@ \pnum An implicitly-declared copy/move constructor is an -\tcode{inline} -\tcode{public} -member of its class. +inline public member of its class. A defaulted copy/\brk{}move constructor for a class \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: \begin{itemize} -\item a variant member with a non-trivial corresponding constructor and - \tcode{X} is a union-like class, - \item a potentially constructed subobject type \tcode{M} (or array thereof) that cannot be copied/moved because overload resolution\iref{over.match}, as applied to find @@ -2697,6 +2691,9 @@ a function that is deleted or inaccessible from the defaulted constructor, +\item a variant member whose corresponding constructor + as selected by overload resolution is non-trivial, + \item any potentially constructed subobject of a type with a destructor that is deleted or inaccessible from the defaulted constructor, or, @@ -2748,8 +2745,9 @@ that is defaulted and not defined as deleted is \term{implicitly defined} -if it is odr-used\iref{basic.def.odr} -or when it is explicitly defaulted after its first declaration. +when it is odr-used\iref{basic.def.odr}, +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. \begin{note} The copy/move constructor is implicitly defined even if the implementation elided its odr-use~(\ref{basic.def.odr}, \ref{class.temporary}). @@ -2982,9 +2980,7 @@ it returns the object for which the assignment operator is invoked, that is, the object assigned to. An implicitly-declared copy/move assignment operator is an -\tcode{inline} -\tcode{public} -member of its class. +inline public member of its class. \pnum A defaulted copy/move assignment operator for @@ -3066,10 +3062,11 @@ that is defaulted and not defined as deleted is \term{implicitly defined} -when -it is odr-used\iref{basic.def.odr} (e.g., when it is selected by overload resolution -to assign to an object of its class type) -or when it is explicitly defaulted after its first declaration. +when it is odr-used\iref{basic.def.odr} +(e.g., when it is selected by overload resolution +to assign to an object of its class type), +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is \tcode{constexpr} if \begin{itemize} \item @@ -3333,3 +3330,158 @@ } \end{codeblock} \end{example} + +\rSec1[class.compare]{Comparisons}% + +\rSec2[class.compare.default]{Defaulted comparison operator functions}% + +\pnum +A defaulted comparison operator function (\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}) +for some class \tcode{C} +shall be a non-template function +declared in the \grammarterm{member-specification} of \tcode{C} +that is +\begin{itemize} +\item a non-static member of \tcode{C} having one parameter of type \tcode{const C\&}, or +\item a friend of \tcode{C} having two parameters of type \tcode{const C\&}. +\end{itemize} + +\rSec2[class.spaceship]{Three-way comparison} +\indextext{operator!three-way comparison!defaulted}% + +\pnum +The direct base class subobjects of \tcode{C}, +in the order of their declaration in the \grammarterm{base-specifier-list} of \tcode{C}, +followed by the non-static data members of \tcode{C}, +in the order of their declaration in the \grammarterm{member-specification} of \tcode{C}, +form a list of subobjects. +In that list, any subobject of array type is recursively expanded +to the sequence of its elements, in the order of increasing subscript. +Let \tcode{x}$_i$ be an lvalue denoting the $i^\textrm{th}$ element +in the expanded list of subobjects for an object \tcode{x} +(of length $n$), +where \tcode{x}$_i$ is +formed by a sequence of +derived-to-base conversions\iref{over.best.ics}, +class member access expressions\iref{expr.ref}, and +array subscript expressions\iref{expr.sub} applied to \tcode{x}. +The type of the expression \tcode{x}$_i$ \tcode{<=>} \tcode{x}$_i$ +is denoted by \tcode{R}$_i$. +It is unspecified +whether virtual base class subobjects are compared more than once. + +\pnum +If the declared return type +of a defaulted three-way comparison operator function +is \tcode{auto}, +then the return type is deduced as +the common comparison type (see below) of +\tcode{R}$_0$, \tcode{R}$_1$, $\cdots$, \tcode{R}$_{n-1}$. +\begin{note} +Otherwise, +the program will be ill-formed +if the expression \tcode{x}$_i$ \tcode{<=>} \tcode{x}$_i$ +is not implicitly convertible to the declared return type for any $i$. +\end{note} +If the return type is deduced as \tcode{void}, +the operator function is defined as deleted. + +\pnum +The return value \tcode{V} of type \tcode{R} +of the defaulted three-way comparison operator function +with parameters \tcode{x} and \tcode{y} of the same type +is determined by comparing corresponding elements +\tcode{x}$_i$ and \tcode{y}$_i$ +in the expanded lists of subobjects for \tcode{x} and \tcode{y} +until the first index $i$ +where \tcode{x}$_i$ \tcode{<=>} \tcode{y}$_i$ +yields a result value \tcode{v}$_i$ where \tcode{v}$_i$\tcode{ != 0}, +contextually converted to \tcode{bool}, yields \tcode{true}; +\tcode{V} is \tcode{v}$_i$ converted to \tcode{R}. +If no such index exists, \tcode{V} is +\tcode{std::strong_ordering::equal} converted to \tcode{R}. + +\pnum +The \defn{common comparison type} \tcode{U} +of a possibly-empty list of $n$ types +\tcode{T}$_0$, \tcode{T}$_1$, $\cdots$, \tcode{T}$_{n-1}$ +is defined as follows: + +\begin{itemize} +\item +If any \tcode{T}$_i$ +is not a comparison category type\iref{cmp.categories}, +\tcode{U} is \tcode{void}. + +\item +Otherwise, if +at least one \tcode{T}$_i$ is \tcode{std::weak_equality}, or +at least one \tcode{T}$_i$ is \tcode{std::strong_equality} and +at least one \tcode{T}$_j$ is \tcode{std::partial_ordering} or + \tcode{std::weak_ordering}, +\tcode{U} is \tcode{std::weak_equality}\iref{cmp.weakeq}. + +\item +Otherwise, if at least one \tcode{T}$_i$ is \tcode{std::strong_equality}, +\tcode{U} is \tcode{std::strong_equality}\iref{cmp.strongeq}. + +\item +Otherwise, if at least one \tcode{T}$_i$ is \tcode{std::partial_ordering}, +\tcode{U} is \tcode{std::partial_ordering}\iref{cmp.partialord}. + +\item +Otherwise, if at least one \tcode{T}$_i$ is \tcode{std::weak_ordering}, +\tcode{U} is \tcode{std::weak_ordering}\iref{cmp.weakord}. + +\item +Otherwise, \tcode{U} is \tcode{std::strong_ordering}\iref{cmp.strongord}. +\begin{note} +In particular, this is the result when $n$ is 0. +\end{note} +\end{itemize} + +\rSec2[class.rel.eq]{Other comparison operators} +\indextext{operator!relational!defaulted}% +\indextext{operator!equality!defaulted}% +\indextext{operator!inequality!defaulted}% + +\pnum +A defaulted relational\iref{expr.rel} or equality\iref{expr.eq} operator function +for some operator \tcode{@} +shall have a declared return type \tcode{bool}. + +\pnum +The operator function with parameters \tcode{x} and \tcode{y} +is defined as deleted if + +\begin{itemize} +\item +overload resolution\iref{over.match}, +as applied to \tcode{x <=> y} +(also considering synthesized candidates with reversed order of parameters\iref{over.match.oper}), +results in an ambiguity +or a function that is deleted or inaccessible from the operator function, +or + +\item +the operator \tcode{@} +cannot be applied to the return type of \tcode{x <=> y} or \tcode{y <=> x}. +\end{itemize} + +Otherwise, the operator function yields +\tcode{x <=> y @ 0} +if an \tcode{operator<=>} +with the original order of parameters was selected, or +\tcode{0 @ y <=> x} +otherwise. + +\pnum +\begin{example} +\begin{codeblock} +struct C { + friend std::strong_equality operator<=>(const C&, const C&); + friend bool operator==(const C& x, const C& y) = default; // OK, returns \tcode{x <=> y == 0} + bool operator<(const C&) = default; // OK, function is deleted +}; +\end{codeblock} +\end{example} diff --git a/source/statements.tex b/source/statements.tex index 2242f280a8..03b745a433 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -12,13 +12,13 @@ \begin{bnf} \nontermdef{statement}\br labeled-statement\br - attribute-specifier-seq\opt expression-statement\br - attribute-specifier-seq\opt compound-statement\br - attribute-specifier-seq\opt selection-statement\br - attribute-specifier-seq\opt iteration-statement\br - attribute-specifier-seq\opt jump-statement\br + \opt{attribute-specifier-seq} expression-statement\br + \opt{attribute-specifier-seq} compound-statement\br + \opt{attribute-specifier-seq} selection-statement\br + \opt{attribute-specifier-seq} iteration-statement\br + \opt{attribute-specifier-seq} jump-statement\br declaration-statement\br - attribute-specifier-seq\opt try-block + \opt{attribute-specifier-seq} try-block \nontermdef{init-statement}\br expression-statement\br @@ -26,7 +26,7 @@ \nontermdef{condition}\br expression\br - attribute-specifier-seq\opt decl-specifier-seq declarator brace-or-equal-initializer + \opt{attribute-specifier-seq} decl-specifier-seq declarator brace-or-equal-initializer \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the respective statement. @@ -102,9 +102,9 @@ \begin{bnf} \nontermdef{labeled-statement}\br - attribute-specifier-seq\opt identifier \terminal{:} statement\br - attribute-specifier-seq\opt{} \terminal{case} constant-expression \terminal{:} statement\br - attribute-specifier-seq\opt{} \terminal{default :} statement + \opt{attribute-specifier-seq} identifier \terminal{:} statement\br + \opt{attribute-specifier-seq} \terminal{case} constant-expression \terminal{:} statement\br + \opt{attribute-specifier-seq} \terminal{default :} statement \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the label. An @@ -139,11 +139,11 @@ \begin{bnf} \nontermdef{expression-statement}\br - expression\opt{} \terminal{;} + \opt{expression} \terminal{;} \end{bnf} The expression is -a discarded-value expression\iref{expr}. +a discarded-value expression\iref{expr.prop}. All \indextext{side effects}% side effects from an expression statement @@ -171,7 +171,7 @@ \begin{bnf} \nontermdef{compound-statement}\br - \terminal{\{} statement-seq\opt{} \terminal{\}} + \terminal{\{} \opt{statement-seq} \terminal{\}} \end{bnf} \begin{bnf} @@ -196,9 +196,9 @@ % \begin{bnf} \nontermdef{selection-statement}\br - \terminal{if constexpr\opt (} init-statement\opt condition \terminal{)} statement\br - \terminal{if constexpr\opt (} init-statement\opt condition \terminal{)} statement \terminal{else} statement\br - \terminal{switch (} init-statement\opt condition \terminal{)} statement + \terminal{if \opt{constexpr} (} \opt{init-statement} condition \terminal{)} statement\br + \terminal{if \opt{constexpr} (} \opt{init-statement} condition \terminal{)} statement \terminal{else} statement\br + \terminal{switch (} \opt{init-statement} condition \terminal{)} statement \end{bnf} See~\ref{dcl.meaning} for the optional \grammarterm{attribute-specifier-seq} in a condition. @@ -295,7 +295,7 @@ An \tcode{if} statement of the form \begin{ncbnf} -\terminal{if constexpr\opt (} init-statement condition \terminal{)} statement +\terminal{if \opt{constexpr} (} init-statement condition \terminal{)} statement \end{ncbnf} is equivalent to @@ -303,14 +303,14 @@ \begin{ncbnftab} \terminal{\{}\br \>init-statement\br -\>\terminal{if constexpr\opt (} condition \terminal{)} statement\br +\>\terminal{if \opt{constexpr} (} condition \terminal{)} statement\br \terminal{\}} \end{ncbnftab} and an \tcode{if} statement of the form \begin{ncbnf} -\terminal{if constexpr\opt (} init-statement condition \terminal{)} statement \terminal{else} statement +\terminal{if \opt{constexpr} (} init-statement condition \terminal{)} statement \terminal{else} statement \end{ncbnf} is equivalent to @@ -318,7 +318,7 @@ \begin{ncbnftab} \terminal{\{}\br \>init-statement\br -\>\terminal{if constexpr\opt (} condition \terminal{)} statement \terminal{else} statement\br +\>\terminal{if \opt{constexpr} (} condition \terminal{)} statement \terminal{else} statement\br \terminal{\}} \end{ncbnftab} @@ -430,14 +430,14 @@ \nontermdef{iteration-statement}\br \terminal{while (} condition \terminal{)} statement\br \terminal{do} statement \terminal{while (} expression \terminal{) ;}\br - \terminal{for (} init-statement condition\opt{} \terminal{;} expression\opt{} \terminal{)} statement\br - \terminal{for (} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement + \terminal{for (} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement\br + \terminal{for (} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement \end{bnf} \begin{bnf} \nontermdef{for-range-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq declarator\br - attribute-specifier-seq\opt decl-specifier-seq ref-qualifier\opt{} \terminal{[} identifier-list \terminal{]} + \opt{attribute-specifier-seq} decl-specifier-seq declarator\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} identifier-list \terminal{]} \end{bnf} \begin{bnf} @@ -568,7 +568,7 @@ The \tcode{for} statement \begin{ncbnf} -\terminal{for (} init-statement condition\opt{} \terminal{;} expression\opt{} \terminal{)} statement +\terminal{for (} init-statement \opt{condition} \terminal{;} \opt{expression} \terminal{)} statement \end{ncbnf} is equivalent to @@ -630,13 +630,14 @@ The range-based \tcode{for} statement \begin{ncbnf} -\terminal{for (} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement +\terminal{for (} \opt{init-statement} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement \end{ncbnf} is equivalent to \begin{ncbnftab} \terminal{\{}\br +\>\opt{init-statement}\br \>\terminal{auto \&\&__range =} for-range-initializer \terminal{;}\br \>\terminal{auto __begin =} begin-expr \terminal{;}\br \>\terminal{auto __end =} end-expr \terminal{;}\br @@ -716,7 +717,7 @@ \nontermdef{jump-statement}\br \terminal{break ;}\br \terminal{continue ;}\br - \terminal{return} expr-or-braced-init-list\opt{} \terminal{;}\br + \terminal{return} \opt{expr-or-braced-init-list} \terminal{;}\br \terminal{goto} identifier \terminal{;} \end{bnf} diff --git a/source/std.tex b/source/std.tex index 555099919e..1e6106fe99 100644 --- a/source/std.tex +++ b/source/std.tex @@ -25,7 +25,6 @@ \usepackage{mathrsfs} % mathscr font \usepackage[final]{microtype} \usepackage{multicol} -\usepackage{xspace} \usepackage{lmodern} \usepackage[T1]{fontenc} \usepackage[pdftex, final]{graphicx} @@ -58,6 +57,7 @@ \input{tables} \makeindex[generalindex] +\makeindex[headerindex] \makeindex[libraryindex] \makeindex[grammarindex] \makeindex[impldefindex] diff --git a/source/strings.tex b/source/strings.tex index 5ed4a61ae7..d308efda0a 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -5,7 +5,7 @@ \pnum This Clause describes components for manipulating sequences of -any non-array POD\iref{basic.types} type. +any non-array trivial\iref{basic.types} type. Such types are called \defnx{char-like types}{char-like type}, and objects of char-like types are called \defnx{char-like objects}{char-like object} or @@ -13,7 +13,7 @@ \pnum The following subclauses describe a -character traits class, a string class, and +character traits class, string classes, and null-terminated sequence utilities, as summarized in Table~\ref{tab:strings.lib.summary}. @@ -590,8 +590,7 @@ \tcode{basic_string<\brk{}wchar_t>}, respectively. \rSec2[string.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{string}}% -\indexlibrary{\idxhdr{string}}% +\indexhdr{string}% \begin{codeblock} #include @@ -791,15 +790,8 @@ wstring to_wstring(double val); wstring to_wstring(long double val); - // \ref{basic.string.hash}, hash support - template struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - namespace pmr { - template > + template> using basic_string = std::basic_string>; using string = basic_string; @@ -808,6 +800,17 @@ using wstring = basic_string; } + // \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; + inline namespace literals { inline namespace string_literals { // \ref{basic.string.literals}, suffix for \tcode{basic_string} literals @@ -872,13 +875,26 @@ \end{itemize} \indexlibrary{\idxcode{basic_string}}% +\indexlibrarymember{traits_type}{basic_string}% +\indexlibrarymember{value_type}{basic_string}% +\indexlibrarymember{allocator_type}{basic_string}% +\indexlibrarymember{size_type}{basic_string}% +\indexlibrarymember{difference_type}{basic_string}% +\indexlibrarymember{pointer}{basic_string}% +\indexlibrarymember{const_pointer}{basic_string}% +\indexlibrarymember{reference}{basic_string}% +\indexlibrarymember{const_reference}{basic_string}% +\indexlibrarymember{iterator}{basic_string}% +\indexlibrarymember{const_iterator}{basic_string}% +\indexlibrarymember{reverse_iterator}{basic_string}% +\indexlibrarymember{const_reverse_iterator}{basic_string}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_string { public: - // types: + // types using traits_type = traits; using value_type = charT; using allocator_type = Allocator; @@ -951,7 +967,7 @@ void reserve(size_type res_arg = 0); void shrink_to_fit(); void clear() noexcept; - bool empty() const noexcept; + [[nodiscard]] bool empty() const noexcept; // \ref{string.access}, element access const_reference operator[](size_type pos) const; @@ -1105,6 +1121,13 @@ int compare(const charT* s) const; int compare(size_type pos1, size_type n1, const charT* s) const; int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; + + bool starts_with(basic_string_view x) const noexcept; + bool starts_with(charT x) const noexcept; + bool starts_with(const charT* x) const; + bool ends_with(basic_string_view x) const noexcept; + bool ends_with(charT x) const noexcept; + bool ends_with(const charT* x) const; }; template x) const noexcept; +bool starts_with(charT x) const noexcept; +bool starts_with(const charT* x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return basic_string_view(data(), size()).starts_with(x); +\end{codeblock} +\end{itemdescr} + +\rSec4[string.ends.with]{\tcode{basic_string::ends_with}} + +\indexlibrarymember{ends_with}{basic_string}% +\begin{itemdecl} +bool ends_with(basic_string_view x) const noexcept; +bool ends_with(charT x) const noexcept; +bool ends_with(const charT* x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return basic_string_view(data(), size()).ends_with(x); +\end{codeblock} +\end{itemdescr} + \rSec2[string.nonmembers]{\tcode{basic_string} non-member functions} \indexlibrary{\idxcode{basic_string}} @@ -4117,7 +4144,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{lhs.swap(rhs);} +Equivalent to \tcode{lhs.swap(rhs)}. \end{itemdescr} \rSec3[string.io]{Inserters and extractors} @@ -4478,11 +4505,19 @@ \indexlibrary{\idxcode{hash}!\idxcode{u16string}}% \indexlibrary{\idxcode{hash}!\idxcode{u32string}}% \indexlibrary{\idxcode{hash}!\idxcode{wstring}}% +\indexlibrary{\idxcode{hash}!\idxcode{pmr::string}}% +\indexlibrary{\idxcode{hash}!\idxcode{pmr::u16string}}% +\indexlibrary{\idxcode{hash}!\idxcode{pmr::u32string}}% +\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; \end{itemdecl} \begin{itemdescr} @@ -4544,7 +4579,7 @@ \pnum The class template \tcode{basic_string_view} describes an object that can refer to a constant contiguous sequence of char-like\iref{strings.general} objects with the first element of the sequence at position zero. -In the rest of this section, the type of the char-like objects held in a \tcode{basic_string_view} object is designated by \tcode{charT}. +In the rest of this subclause, the type of the char-like objects held in a \tcode{basic_string_view} object is designated by \tcode{charT}. \pnum \begin{note} @@ -4557,8 +4592,7 @@ \rSec2[string.view.synop]{Header \tcode{} synopsis} -\indextext{\idxhdr{string_view}}% -\indexlibrary{\idxhdr{string_view}}% +\indexhdr{string_view}% \begin{codeblock} namespace std { // \ref{string.view.template}, class template \tcode{basic_string_view} @@ -4624,6 +4658,18 @@ \rSec2[string.view.template]{Class template \tcode{basic_string_view}} \indexlibrary{\idxcode{basic_string_view}}% +\indexlibrarymember{traits_type}{basic_string_view}% +\indexlibrarymember{value_type}{basic_string_view}% +\indexlibrarymember{pointer}{basic_string_view}% +\indexlibrarymember{const_pointer}{basic_string_view}% +\indexlibrarymember{reference}{basic_string_view}% +\indexlibrarymember{const_reference}{basic_string_view}% +\indexlibrarymember{const_iterator}{basic_string_view}% +\indexlibrarymember{iterator}{basic_string_view}% +\indexlibrarymember{const_reverse_iterator}{basic_string_view}% +\indexlibrarymember{reverse_iterator}{basic_string_view}% +\indexlibrarymember{size_type}{basic_string_view}% +\indexlibrarymember{difference_type}{basic_string_view}% \begin{codeblock} template> class basic_string_view { @@ -4664,7 +4710,7 @@ constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; - constexpr bool empty() const noexcept; + [[nodiscard]] constexpr bool empty() const noexcept; // \ref{string.view.access}, element access constexpr const_reference operator[](size_type pos) const; @@ -4691,6 +4737,13 @@ constexpr int compare(size_type pos1, size_type n1, const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; + constexpr bool starts_with(basic_string_view x) const noexcept; + constexpr bool starts_with(charT x) const noexcept; + constexpr bool starts_with(const charT* x) const; + constexpr bool ends_with(basic_string_view x) const noexcept; + constexpr bool ends_with(charT x) const noexcept; + constexpr bool ends_with(const charT* x) const; + constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find(charT c, size_type pos = 0) const noexcept; constexpr size_type find(const charT* s, size_type pos, size_type n) const; @@ -4904,7 +4957,7 @@ \indexlibrarymember{empty}{basic_string_view}% \begin{itemdecl} -constexpr bool empty() const noexcept; +[[nodiscard]] constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5193,14 +5246,83 @@ Equivalent to: \tcode{return substr(pos1, n1).compare(basic_string_view(s, n2));} \end{itemdescr} +\indexlibrarymember{starts_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool starts_with(basic_string_view x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return compare(0, npos, x) == 0;} +\end{itemdescr} + +\indexlibrarymember{starts_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool starts_with(charT x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return starts_with(basic_string_view(\&x, 1));} +\end{itemdescr} + +\indexlibrarymember{starts_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool starts_with(const charT* x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return starts_with(basic_string_view(x));} +\end{itemdescr} + +\indexlibrarymember{ends_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool ends_with(basic_string_view x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return size() >= x.size() && compare(size() - x.size(), npos, x) == 0; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{ends_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool ends_with(charT x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ends_with(basic_string_view(\&x, 1));} +\end{itemdescr} + +\indexlibrarymember{ends_with}{basic_string_view}% +\begin{itemdecl} +constexpr bool ends_with(const charT* x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ends_with(basic_string_view(x));} +\end{itemdescr} + \rSec3[string.view.find]{Searching} \pnum -This section specifies the \tcode{basic_string_view} member functions named +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 section have complexity \bigoh{\tcode{size() * str.size()}} at worst, +Member functions in this subclause have complexity \bigoh{\tcode{size() * str.size()}} at worst, although implementations should do better. \pnum @@ -5602,8 +5724,7 @@ \rSec2[cctype.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cctype}}% -\indexlibrary{\idxhdr{cctype}}% +\indexhdr{cctype}% \indexlibrary{\idxcode{isalnum}}% \indexlibrary{\idxcode{isalpha}}% \indexlibrary{\idxcode{isblank}}% @@ -5638,8 +5759,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{ctype.h}}% -\indexlibrary{\idxhdr{ctype.h}}% +\indexhdr{ctype.h}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}. @@ -5647,8 +5767,7 @@ \rSec2[cwctype.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cwctype}}% -\indexlibrary{\idxhdr{cwctype}}% +\indexhdr{cwctype}% \indexlibrary{\idxcode{wint_t}}% \indexlibrary{\idxcode{wctrans_t}}% \indexlibrary{\idxcode{wctype_t}}% @@ -5701,8 +5820,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{wctype.h}}% -\indexlibrary{\idxhdr{wctype.h}}% +\indexhdr{wctype.h}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}. @@ -5710,8 +5828,7 @@ \rSec2[cstring.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cstring}}% -\indexlibrary{\idxhdr{cstring}}% +\indexhdr{cstring}% \indexlibrary{\idxcode{memchr}}% \indexlibrary{\idxcode{memcmp}}% \indexlibrary{\idxcode{memcpy}}% @@ -5772,8 +5889,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{string.h}}% -\indexlibrary{\idxhdr{string.h}}% +\indexhdr{string.h}% The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}. @@ -5798,8 +5914,7 @@ \rSec2[cwchar.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cwchar}}% -\indexlibrary{\idxhdr{cwchar}}% +\indexhdr{cwchar}% \indexlibrary{\idxcode{NULL}}% \indexlibrary{\idxcode{WCHAR_MAX}}% \indexlibrary{\idxcode{WCHAR_MIN}}% @@ -5950,8 +6065,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{wchar.h}}% -\indexlibrary{\idxhdr{wchar.h}}% +\indexhdr{wchar.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 a type \tcode{wchar_t}. @@ -5968,8 +6082,7 @@ \rSec2[cuchar.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cuchar}}% -\indexlibrary{\idxhdr{cuchar}}% +\indexhdr{cuchar}% \indexlibrary{\idxcode{mbstate_t}}% \indexlibrary{\idxcode{size_t}}% \indexlibrary{\idxcode{mbrtoc16}}% @@ -5989,8 +6102,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{uchar.h}}% -\indexlibrary{\idxhdr{uchar.h}}% +\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 @@ -6001,10 +6113,8 @@ \rSec2[c.mb.wcs]{Multibyte / wide string and character conversion functions} \pnum -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% -\indextext{\idxhdr{cwchar}}% -\indexlibrary{\idxhdr{cwchar}}% +\indexhdr{cstdlib}% +\indexhdr{cwchar}% \begin{note} The headers \tcode{}\iref{cstdlib.syn} and \tcode{}\iref{cwchar.syn} diff --git a/source/support.tex b/source/support.tex index e2a85f5d77..f456688cac 100644 --- a/source/support.tex +++ b/source/support.tex @@ -6,7 +6,7 @@ \pnum This Clause describes the function signatures that are called implicitly, and the types of objects generated implicitly, during the execution -of some \Cpp programs. +of some \Cpp{} programs. It also describes the headers that declare these function signatures and define any related types. @@ -14,7 +14,7 @@ The following subclauses describe common type definitions used throughout the library, characteristics of the predefined types, -functions supporting start and termination of a \Cpp program, +functions supporting start and termination of a \Cpp{} program, support for dynamic memory management, support for dynamic type identification, support for exception processing, support for initializer lists, @@ -33,6 +33,7 @@ \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep +\ref{cmp} & Comparisons & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ & & \tcode{} \\ & & \tcode{} \\ @@ -60,13 +61,13 @@ enum class byte : unsigned char {}; // \ref{support.types.byteops}, \tcode{byte} type operations - template + template constexpr byte& operator<<=(byte& b, IntType shift) noexcept; - template + template constexpr byte operator<<(byte b, IntType shift) noexcept; - template + template constexpr byte& operator>>=(byte& b, IntType shift) noexcept; - template + template constexpr byte operator>>(byte b, IntType shift) noexcept; constexpr byte& operator|=(byte& l, byte r) noexcept; constexpr byte operator|(byte l, byte r) noexcept; @@ -75,7 +76,7 @@ constexpr byte& operator^=(byte& l, byte r) noexcept; constexpr byte operator^(byte l, byte r) noexcept; constexpr byte operator~(byte b) noexcept; - template + template constexpr IntType to_integer(byte b) noexcept; } @@ -97,8 +98,7 @@ \rSec2[cstdlib.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% \indexlibrary{\idxcode{EXIT_FAILURE}}% \indexlibrary{\idxcode{EXIT_SUCCESS}}% \indexlibrary{\idxcode{MB_CUR_MAX}}% @@ -331,7 +331,7 @@ \pnum The type \indexlibrary{\idxcode{max_align_t}}% -\tcode{max_align_t} is a POD type whose alignment requirement +\tcode{max_align_t} is a trivial type whose alignment requirement is at least as great as that of every scalar type, and whose alignment requirement is supported in every context\iref{basic.align}. @@ -341,7 +341,7 @@ \indexlibrarymember{operator<<=}{byte}% \begin{itemdecl} -template +template constexpr byte& operator<<=(byte& b, IntType shift) noexcept; \end{itemdecl} @@ -350,12 +350,12 @@ \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: -\tcode{return b = byte(static_cast(b) << shift);} +\tcode{return b = b << shift;} \end{itemdescr} \indexlibrarymember{operator<<}{byte}% \begin{itemdecl} -template +template constexpr byte operator<<(byte b, IntType shift) noexcept; \end{itemdecl} @@ -364,12 +364,15 @@ \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: -\tcode{return byte(static_cast(b) << shift);} +\begin{codeblock} +return static_cast(static_cast( + static_cast(b) << shift)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator>>=}{byte}% \begin{itemdecl} -template +template constexpr byte& operator>>=(byte& b, IntType shift) noexcept; \end{itemdecl} @@ -378,12 +381,12 @@ \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: -\tcode{return b = byte(static_cast(b) >> shift);} +\tcode{return b >> shift;} \end{itemdescr} \indexlibrarymember{operator>>}{byte}% \begin{itemdecl} -template +template constexpr byte operator>>(byte b, IntType shift) noexcept; \end{itemdecl} @@ -392,7 +395,10 @@ \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: -\tcode{return byte(static_cast(b) >> shift);} +\begin{codeblock} +return static_cast(static_cast( + static_cast(b) >> shift)); +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator"|=}{byte}% @@ -401,10 +407,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum \effects Equivalent to: -\begin{codeblock} -return l = byte(static_cast(l) | static_cast(r)); -\end{codeblock} +\pnum \effects Equivalent to: \tcode{return l = l | r;} \end{itemdescr} \indexlibrarymember{operator"|}{byte}% @@ -415,7 +418,8 @@ \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} -return byte(static_cast(l) | static_cast(r)); +return static_cast(static_cast(static_cast(l) | + static_cast(r))); \end{codeblock} \end{itemdescr} @@ -425,10 +429,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum \effects Equivalent to: -\begin{codeblock} -return l = byte(static_cast(l) & static_cast(r)); -\end{codeblock} +\pnum \effects Equivalent to: \tcode{return l = l \& r;} \end{itemdescr} \indexlibrarymember{operator\&}{byte}% @@ -439,7 +440,8 @@ \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} -return byte(static_cast(l) & static_cast(r)); +return static_cast(static_cast(static_cast(l) & + static_cast(r))); \end{codeblock} \end{itemdescr} @@ -449,10 +451,7 @@ \end{itemdecl} \begin{itemdescr} -\pnum \effects Equivalent to: -\begin{codeblock} -return l = byte(static_cast(l) ^ static_cast(r)); -\end{codeblock} +\pnum \effects Equivalent to: \tcode{return l = l \^ r;} \end{itemdescr} \indexlibrarymember{operator\caret}{byte}% @@ -463,7 +462,8 @@ \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} -return byte(static_cast(l) ^ static_cast(r)); +return static_cast(static_cast(static_cast(l) ^ + static_cast(r))); \end{codeblock} \end{itemdescr} @@ -473,12 +473,16 @@ \end{itemdecl} \begin{itemdescr} -\pnum \effects Equivalent to: \tcode{return byte(\~static_cast(b));} +\pnum \effects Equivalent to: +\begin{codeblock} +return static_cast(static_cast( + ~static_cast(b))); +\end{codeblock} \end{itemdescr} \indexlibrarymember{to_integer}{byte}% \begin{itemdecl} -template +template constexpr IntType to_integer(byte b) noexcept; \end{itemdecl} @@ -486,7 +490,7 @@ \pnum \remarks This function shall not participate in overload resolution unless \tcode{is_integral_v} is \tcode{true}. -\pnum \effects Equivalent to: \tcode{return IntType(b);} +\pnum \effects Equivalent to: \tcode{return static_cast(b);} \end{itemdescr} \rSec1[support.limits]{Implementation properties} @@ -502,8 +506,7 @@ arithmetic types\iref{basic.fundamental}. \rSec2[limits.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{limits}}% -\indexlibrary{\idxhdr{limits}}% +\indexhdr{limits}% \indextext{\idxcode{numeric_limits}}% \indexlibrary{\idxcode{numeric_limits}}% \indexlibrary{\idxcode{float_round_style}}% @@ -628,7 +631,7 @@ The \indexlibrary{\idxcode{numeric_limits}}% \tcode{numeric_limits} -class template provides a \Cpp program with information about various properties of +class template provides a \Cpp{} program with information about various properties of the implementation's representation of the arithmetic types. @@ -1502,8 +1505,7 @@ \rSec1[cstdint]{Integer types} \rSec2[cstdint.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cstdint}}% -\indexlibrary{\idxhdr{cstdint}}% +\indexhdr{cstdint}% \indexlibrary{\idxcode{int8_t}}% \indexlibrary{\idxcode{int16_t}}% \indexlibrary{\idxcode{int32_t}}% @@ -1600,7 +1602,7 @@ \rSec1[support.start.term]{Start and termination} \pnum -\indextext{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% \begin{note} The header \tcode{}\iref{cstdlib.syn} declares the functions described in this subclause. @@ -1809,8 +1811,7 @@ It also defines components for reporting storage management errors. \rSec2[new.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{new}}% -\indexlibrary{\idxhdr{new}}% +\indexhdr{new}% \indexlibrary{\idxcode{align_val_t}}% \indexlibrary{\idxcode{nothrow_t}}% \indexlibrary{\idxcode{nothrow}}% @@ -1829,17 +1830,18 @@ new_handler set_new_handler(new_handler new_p) noexcept; // \ref{ptr.launder}, pointer optimization barrier - template constexpr T* launder(T* p) noexcept; + template [[nodiscard]] constexpr T* launder(T* p) noexcept; // \ref{hardware.interference}, hardware interference size inline constexpr size_t hardware_destructive_interference_size = @\impdef{}@; inline constexpr size_t hardware_constructive_interference_size = @\impdef{}@; } -void* operator new(std::size_t size); -void* operator new(std::size_t size, std::align_val_t alignment); -void* operator new(std::size_t size, const std::nothrow_t&) noexcept; -void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new(std::size_t size); +[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment); +[[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; void operator delete(void* ptr) noexcept; void operator delete(void* ptr, std::size_t size) noexcept; @@ -1848,11 +1850,11 @@ void operator delete(void* ptr, const std::nothrow_t&) noexcept; void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept; -void* operator new[](std::size_t size); -void* operator new[](std::size_t size, std::align_val_t alignment); -void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; -void* operator new[](std::size_t size, std::align_val_t alignment, - const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new[](std::size_t size); +[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment); +[[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; void operator delete[](void* ptr) noexcept; void operator delete[](void* ptr, std::size_t size) noexcept; @@ -1861,8 +1863,8 @@ void operator delete[](void* ptr, const std::nothrow_t&) noexcept; void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept; -void* operator new (std::size_t size, void* ptr) noexcept; -void* operator new[](std::size_t size, void* ptr) noexcept; +[[nodiscard]] void* operator new (std::size_t size, void* ptr) noexcept; +[[nodiscard]] void* operator new[](std::size_t size, void* ptr) noexcept; void operator delete (void* ptr, void*) noexcept; void operator delete[](void* ptr, void*) noexcept; \end{codeblock} @@ -1879,17 +1881,17 @@ the behavior is undefined. \newcommand{\replaceabledesc}[1]{% -A \Cpp program may define functions with #1 of these function signatures, +A \Cpp{} program may define functions with #1 of these function signatures, and thereby displace the default versions defined by the -\Cpp standard library.% +\Cpp{} standard library.% } \rSec3[new.delete.single]{Single-object forms} \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new(std::size_t size); -void* operator new(std::size_t size, std::align_val_t alignment); +[[nodiscard]] void* operator new(std::size_t size); +[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment); \end{itemdecl} \begin{itemdescr} @@ -1953,8 +1955,9 @@ \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new(std::size_t size, const std::nothrow_t&) noexcept; -void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1962,7 +1965,7 @@ \effects Same as above, except that these are called by a placement version of a \grammarterm{new-expression} -when a \Cpp program prefers a null pointer result as an error indication, +when a \Cpp{} program prefers a null pointer result as an error indication, instead of a \tcode{bad_alloc} exception. @@ -2158,8 +2161,8 @@ \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new[](std::size_t size); -void* operator new[](std::size_t size, std::align_val_t alignment); +[[nodiscard]] void* operator new[](std::size_t size); +[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment); \end{itemdecl} \begin{itemdescr} @@ -2215,8 +2218,9 @@ \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; -void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; +[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2224,7 +2228,7 @@ \effects Same as above, except that these are called by a placement version of a \grammarterm{new-expression} -when a \Cpp program prefers a null pointer result as an error indication, +when a \Cpp{} program prefers a null pointer result as an error indication, instead of a \tcode{bad_alloc} exception. @@ -2392,14 +2396,14 @@ \rSec3[new.delete.placement]{Non-allocating forms} \pnum -These functions are reserved; a \Cpp program may not define functions that displace -the versions in the \Cpp standard library\iref{constraints}. +These functions are reserved; a \Cpp{} program may not define functions that displace +the versions in the \Cpp{} standard library\iref{constraints}. The provisions of~\ref{basic.stc.dynamic} do not apply to these reserved placement forms of \tcode{operator new} and \tcode{operator delete}. \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new(std::size_t size, void* ptr) noexcept; +[[nodiscard]] void* operator new(std::size_t size, void* ptr) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2424,7 +2428,7 @@ \indexlibrary{\idxcode{new}!\idxcode{operator}}% \begin{itemdecl} -void* operator new[](std::size_t size, void* ptr) noexcept; +[[nodiscard]] void* operator new[](std::size_t size, void* ptr) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2557,7 +2561,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_alloc::what}} \ntbs. +An \impldef{return value of \tcode{bad_alloc::what}} \ntbs{}. \pnum \remarks @@ -2603,7 +2607,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_array_new_length::what}} \ntbs. +An \impldef{return value of \tcode{bad_array_new_length::what}} \ntbs{}. \pnum \remarks @@ -2687,7 +2691,7 @@ \indexlibrary{\idxcode{launder}}% \begin{itemdecl} -template constexpr T* launder(T* p) noexcept; +template [[nodiscard]] constexpr T* launder(T* p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2805,8 +2809,7 @@ It also defines two types for reporting dynamic type identification errors. \rSec2[typeinfo.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{typeinfo}}% -\indexlibrary{\idxhdr{typeinfo}}% +\indexhdr{typeinfo}% \indexlibrary{\idxcode{type_info}}% \indexlibrary{\idxcode{bad_cast}}% \indexlibrary{\idxcode{bad_typeid}}% @@ -2919,7 +2922,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{type_info::name()}} \ntbs. +An \impldef{return value of \tcode{type_info::name()}} \ntbs{}. \pnum \remarks @@ -2986,7 +2989,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_cast::what}} \ntbs. +An \impldef{return value of \tcode{bad_cast::what}} \ntbs{}. \pnum \remarks @@ -3053,7 +3056,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_typeid::what}} \ntbs. +An \impldef{return value of \tcode{bad_typeid::what}} \ntbs{}. \pnum \remarks @@ -3067,11 +3070,10 @@ \pnum The header \tcode{} -defines several types and functions related to the handling of exceptions in a \Cpp program. +defines several types and functions related to the handling of exceptions in a \Cpp{} program. \rSec2[exception.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{exception}}% -\indexlibrary{\idxhdr{exception}}% +\indexhdr{exception}% \begin{codeblock} namespace std { @@ -3092,8 +3094,8 @@ [[noreturn]] void rethrow_exception(exception_ptr p); template exception_ptr make_exception_ptr(E e) noexcept; - template [[noreturn]] void throw_with_nested(T&& t); - template void rethrow_if_nested(const E& e); + template [[noreturn]] void throw_with_nested(T&& t); + template void rethrow_if_nested(const E& e); } \end{codeblock} @@ -3118,7 +3120,7 @@ \tcode{exception} defines the base class for the types of objects thrown as exceptions by -\Cpp standard library components, and certain +\Cpp{} standard library components, and certain expressions, to report errors detected during program execution. \pnum @@ -3180,7 +3182,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{exception::what}} \ntbs. +An \impldef{return value of \tcode{exception::what}} \ntbs{}. \pnum \remarks @@ -3249,7 +3251,7 @@ \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_exception::what}} \ntbs. +An \impldef{return value of \tcode{bad_exception::what}} \ntbs{}. \pnum \remarks @@ -3487,7 +3489,7 @@ }; template [[noreturn]] void throw_with_nested(T&& t); - template void rethrow_if_nested(const E& e); + template void rethrow_if_nested(const E& e); } \end{codeblock} @@ -3534,7 +3536,7 @@ \indexlibrarymember{throw_with_nested}{nested_exception}% \begin{itemdecl} -template [[noreturn]] void throw_with_nested(T&& t); +template [[noreturn]] void throw_with_nested(T&& t); \end{itemdecl} \begin{itemdescr} @@ -3556,7 +3558,7 @@ \indexlibrarymember{rethrow_if_nested}{nested_exception}% \begin{itemdecl} -template void rethrow_if_nested(const E& e); +template void rethrow_if_nested(const E& e); \end{itemdecl} \begin{itemdescr} @@ -3574,8 +3576,7 @@ \rSec1[support.initlist]{Initializer lists} -\indextext{\idxhdr{initializer_list}}% -\indexlibrary{\idxhdr{initializer_list}}% +\indexhdr{initializer_list}% \pnum The header \tcode{} defines a class template and several support functions related to list-initialization~(see \ref{dcl.init.list}). @@ -3698,19 +3699,867 @@ \returns \tcode{il.end()}. \end{itemdescr} +\rSec1[cmp]{Comparisons} + +\rSec2[cmp.syn]{Header \tcode{} synopsis} + +\pnum +The header \tcode{} specifies types, objects, and functions +for use primarily in connection with +the three-way comparison operator\iref{expr.spaceship}. + +\indexhdr{compare}% +\indexlibrary{\idxcode{is_eq}}% +\indexlibrary{\idxcode{is_neq}}% +\indexlibrary{\idxcode{is_lt}}% +\indexlibrary{\idxcode{is_lteq}}% +\indexlibrary{\idxcode{is_gt}}% +\indexlibrary{\idxcode{is_geq}}% +\indexlibrary{\idxcode{is_gteq}}% +\indexlibrary{\idxcode{common_comparison_category_t}}% +\begin{codeblock} +namespace std { + // \ref{cmp.categories}, comparison category types + class weak_equality; + class strong_equality; + class partial_ordering; + class weak_ordering; + class strong_ordering; + + // named comparison functions + constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; } + constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; } + constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } + constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } + constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } + constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } + + // \ref{cmp.common}, common comparison category type + template + struct common_comparison_category { + using type = @\seebelow@; + }; + template + using common_comparison_category_t = typename common_comparison_category::type; + + // \ref{cmp.alg}, comparison algorithms + template constexpr strong_ordering strong_order(const T& a, const T& b); + template constexpr weak_ordering weak_order(const T& a, const T& b); + template constexpr partial_ordering partial_order(const T& a, const T& b); + template constexpr strong_equality strong_equal(const T& a, const T& b); + template constexpr weak_equality weak_equal(const T& a, const T& b); +} +\end{codeblock} + +\rSec2[cmp.categories]{Comparison category types} + +\rSec3[cmp.categories.pre]{Preamble} + +\pnum +The types +\tcode{weak_equality}, +\tcode{strong_equality}, +\tcode{partial_ordering}, +\tcode{weak_ordering}, and +\tcode{strong_ordering} +are collectively termed the \defn{comparison category types}. +Each is specified in terms of an exposition-only data member named \tcode{value} +whose value typically corresponds to that of an enumerator +from one of the following exposition-only enumerations: + +\begin{codeblock} +enum class eq { equal = 0, equivalent = equal, + nonequal = 1, nonequivalent = nonequal }; // \expos +enum class ord { less = -1, greater = 1 }; // \expos +enum class ncmp { unordered = -127 }; // \expos +\end{codeblock} + +\pnum +\begin{note} +The types \tcode{strong_ordering} and \tcode{weak_equality} +correspond, respectively, to the terms +total ordering and equivalence in mathematics. +\end{note} + +\pnum +The relational and equality operators for the comparison category types +are specified with an anonymous parameter of unspecified type. +This type shall be selected by the implementation such that +these parameters can accept literal \tcode{0} as a corresponding argument. +\begin{example} +\tcode{nullptr_t} +satisfies this requirement. +\end{example} +In this context, the behavior of a program that supplies +an argument other than a literal \tcode{0} is undefined. + +\pnum +For the purposes of this subclause, +\defn{substitutability} is the property that \tcode{f(a) == f(b)} is \tcode{true} +whenever \tcode{a == b} is true, +where \tcode{f} denotes a function that reads only comparison-salient state +that is accessible via the argument's public const members. + +\rSec3[cmp.weakeq]{Class \tcode{weak_equality}} + +\pnum +The \tcode{weak_equality} type is typically used +as the result type of a three-way comparison operator\iref{expr.spaceship} +that (a) admits only equality and inequality comparisons, +and (b) does not imply substitutability. + +\indexlibrary{\idxcode{weak_equality}}% +\indexlibrarymember{equivalent}{weak_equality}% +\indexlibrarymember{nonequivalent}{weak_equality}% +\begin{codeblock} +namespace std { + class weak_equality { + int value; // \expos + + // exposition-only constructor + explicit constexpr weak_equality(eq v) noexcept : value(int(v)) {} // \expos + + public: + // valid values + static const weak_equality equivalent; + static const weak_equality nonequivalent; + + // comparisons + friend constexpr bool operator==(weak_equality v, @\unspec@) noexcept; + friend constexpr bool operator!=(weak_equality v, @\unspec@) noexcept; + friend constexpr bool operator==(@\unspec@, weak_equality v) noexcept; + friend constexpr bool operator!=(@\unspec@, weak_equality v) noexcept; + }; + + // valid values' definitions + inline constexpr weak_equality weak_equality::equivalent(eq::equivalent); + inline constexpr weak_equality weak_equality::nonequivalent(eq::nonequivalent); +} +\end{codeblock} + +\indexlibrarymember{operator==}{weak_equality}% +\begin{itemdecl} +constexpr bool operator==(weak_equality v, @\unspec@) noexcept; +constexpr bool operator==(@\unspec@, weak_equality v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value == 0}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{weak_equality}% +\begin{itemdecl} +constexpr bool operator!=(weak_equality v, @\unspec@) noexcept; +constexpr bool operator!=(@\unspec@, weak_equality v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value != 0}. +\end{itemdescr} + +\rSec3[cmp.strongeq]{Class \tcode{strong_equality}} + +\pnum +The \tcode{strong_equality} type is typically used +as the result type of a three-way comparison operator\iref{expr.spaceship} +that (a) admits only equality and inequality comparisons, +and (b) does imply substitutability. + +\indexlibrary{\idxcode{strong_equality}}% +\indexlibrarymember{equal}{strong_equality}% +\indexlibrarymember{nonequal}{strong_equality}% +\indexlibrarymember{equivalent}{strong_equality}% +\indexlibrarymember{nonequivalent}{strong_equality}% +\begin{codeblock} +namespace std { + class strong_equality { + int value; // \expos + + // exposition-only constructor + explicit constexpr strong_equality(eq v) noexcept : value(int(v)) {} // \expos + + public: + // valid values + static const strong_equality equal; + static const strong_equality nonequal; + static const strong_equality equivalent; + static const strong_equality nonequivalent; + + // conversion + constexpr operator weak_equality() const noexcept; + + // comparisons + friend constexpr bool operator==(strong_equality v, @\unspec@) noexcept; + friend constexpr bool operator!=(strong_equality v, @\unspec@) noexcept; + friend constexpr bool operator==(@\unspec@, strong_equality v) noexcept; + friend constexpr bool operator!=(@\unspec@, strong_equality v) noexcept; + }; + + // valid values' definitions + inline constexpr strong_equality strong_equality::equal(eq::equal); + inline constexpr strong_equality strong_equality::nonequal(eq::nonequal); + inline constexpr strong_equality strong_equality::equivalent(eq::equivalent); + inline constexpr strong_equality strong_equality::nonequivalent(eq::nonequivalent); +} +\end{codeblock} + +\indexlibrarymember{operator weak_equality}{strong_equality}% +\begin{itemdecl} +constexpr operator weak_equality() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{value == 0 ?\ weak_equality::equivalent :\ weak_equality::nonequivalent}. +\end{itemdescr} + +\indexlibrarymember{operator==}{strong_equality}% +\begin{itemdecl} +constexpr bool operator==(strong_equality v, @\unspec@) noexcept; +constexpr bool operator==(@\unspec@, strong_equality v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value == 0}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{strong_equality}% +\begin{itemdecl} +constexpr bool operator!=(strong_equality v, @\unspec@) noexcept; +constexpr bool operator!=(@\unspec@, strong_equality v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value != 0}. +\end{itemdescr} + +\rSec3[cmp.partialord]{Class \tcode{partial_ordering}} + +\pnum +The \tcode{partial_ordering} type is typically used +as the result type of a three-way comparison operator\iref{expr.spaceship} +that (a) admits all of the six two-way comparison operators (\ref{expr.rel}, \ref{expr.eq}), +(b) does not imply substitutability, +and (c) permits two values to be incomparable.% +\footnote{That is, \tcode{a < b}, \tcode{a == b}, and \tcode{a > b} might all be \tcode{false}.} + +\indexlibrary{\idxcode{partial_ordering}}% +\indexlibrarymember{less}{partial_ordering}% +\indexlibrarymember{equivalent}{partial_ordering}% +\indexlibrarymember{greater}{partial_ordering}% +\indexlibrarymember{unordered}{partial_ordering}% +\begin{codeblock} +namespace std { + class partial_ordering { + int value; // \expos + bool is_ordered; // \expos + + // exposition-only constructors + explicit constexpr + partial_ordering(eq v) noexcept : value(int(v)), is_ordered(true) {} // \expos + explicit constexpr + partial_ordering(ord v) noexcept : value(int(v)), is_ordered(true) {} // \expos + explicit constexpr + partial_ordering(ncmp v) noexcept : value(int(v)), is_ordered(false) {} // \expos + + public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // conversion + constexpr operator weak_equality() const noexcept; + + // comparisons + friend constexpr bool operator==(partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator!=(partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator< (partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator<=(partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator> (partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator>=(partial_ordering v, @\unspec@) noexcept; + friend constexpr bool operator==(@\unspec@, partial_ordering v) noexcept; + friend constexpr bool operator!=(@\unspec@, partial_ordering v) noexcept; + friend constexpr bool operator< (@\unspec@, partial_ordering v) noexcept; + friend constexpr bool operator<=(@\unspec@, partial_ordering v) noexcept; + friend constexpr bool operator> (@\unspec@, partial_ordering v) noexcept; + friend constexpr bool operator>=(@\unspec@, partial_ordering v) noexcept; + }; + + // valid values' definitions + inline constexpr partial_ordering partial_ordering::less(ord::less); + inline constexpr partial_ordering partial_ordering::equivalent(eq::equivalent); + inline constexpr partial_ordering partial_ordering::greater(ord::greater); + inline constexpr partial_ordering partial_ordering::unordered(ncmp::unordered); +} +\end{codeblock} + +\indexlibrarymember{operator weak_equality}{partial_ordering}% +\begin{itemdecl} +constexpr operator weak_equality() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{value == 0 ?\ weak_equality::equivalent :\ weak_equality::nonequivalent}. +\begin{note} +The result is independent of the \tcode{is_ordered} member. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator==}{partial_ordering}% +\indexlibrarymember{operator<}{partial_ordering}% +\indexlibrarymember{operator<=}{partial_ordering}% +\indexlibrarymember{operator>}{partial_ordering}% +\indexlibrarymember{operator>=}{partial_ordering}% +\begin{itemdecl} +constexpr bool operator==(partial_ordering v, @\unspec@) noexcept; +constexpr bool operator< (partial_ordering v, @\unspec@) noexcept; +constexpr bool operator<=(partial_ordering v, @\unspec@) noexcept; +constexpr bool operator> (partial_ordering v, @\unspec@) noexcept; +constexpr bool operator>=(partial_ordering v, @\unspec@) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +For \tcode{operator@}, \tcode{v.is_ordered \&\& v.value @ 0}. +\end{itemdescr} + +\indexlibrarymember{operator==}{partial_ordering}% +\indexlibrarymember{operator<}{partial_ordering}% +\indexlibrarymember{operator<=}{partial_ordering}% +\indexlibrarymember{operator>}{partial_ordering}% +\indexlibrarymember{operator>=}{partial_ordering}% +\begin{itemdecl} +constexpr bool operator==(@\unspec@, partial_ordering v) noexcept; +constexpr bool operator< (@\unspec@, partial_ordering v) noexcept; +constexpr bool operator<=(@\unspec@, partial_ordering v) noexcept; +constexpr bool operator> (@\unspec@, partial_ordering v) noexcept; +constexpr bool operator>=(@\unspec@, partial_ordering v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +For \tcode{operator@}, \tcode{v.is_ordered \&\& 0 @ v.value}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{partial_ordering}% +\begin{itemdecl} +constexpr bool operator!=(partial_ordering v, @\unspec@) noexcept; +constexpr bool operator!=(@\unspec@, partial_ordering v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +For \tcode{operator@}, \tcode{!v.is_ordered || v.value != 0}. +\end{itemdescr} + +\rSec3[cmp.weakord]{Class \tcode{weak_ordering}} + +\pnum +The \tcode{weak_ordering} type is typically used +as the result type of a three-way comparison operator\iref{expr.spaceship} +that (a) admits all of the six two-way comparison operators (\ref{expr.rel}, \ref{expr.eq}), +and (b) does not imply substitutability. + +\indexlibrary{\idxcode{weak_ordering}}% +\indexlibrarymember{less}{weak_ordering}% +\indexlibrarymember{equivalent}{weak_ordering}% +\indexlibrarymember{greater}{weak_ordering}% +\begin{codeblock} +namespace std { + class weak_ordering { + 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 + + public: + // valid values + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + // conversions + constexpr operator weak_equality() const noexcept; + constexpr operator partial_ordering() const noexcept; + + // comparisons + friend constexpr bool operator==(weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator!=(weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator< (weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator<=(weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator> (weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator>=(weak_ordering v, @\unspec@) noexcept; + friend constexpr bool operator==(@\unspec@, weak_ordering v) noexcept; + friend constexpr bool operator!=(@\unspec@, weak_ordering v) noexcept; + friend constexpr bool operator< (@\unspec@, weak_ordering v) noexcept; + friend constexpr bool operator<=(@\unspec@, weak_ordering v) noexcept; + friend constexpr bool operator> (@\unspec@, weak_ordering v) noexcept; + friend constexpr bool operator>=(@\unspec@, weak_ordering v) noexcept; + }; + + // valid values' definitions + inline constexpr weak_ordering weak_ordering::less(ord::less); + inline constexpr weak_ordering weak_ordering::equivalent(eq::equivalent); + inline constexpr weak_ordering weak_ordering::greater(ord::greater); +} +\end{codeblock} + +\indexlibrarymember{operator weak_equality}{weak_ordering}% +\begin{itemdecl} +constexpr operator weak_equality() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{value == 0 ?\ weak_equality::equivalent :\ weak_equality::nonequivalent}. +\end{itemdescr} + +\indexlibrarymember{operator partial_ordering}{weak_ordering}% +\begin{itemdecl} +constexpr operator partial_ordering() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +value == 0 ? partial_ordering::equivalent : +value < 0 ? partial_ordering::less : + partial_ordering::greater +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator==}{weak_ordering}% +\indexlibrarymember{operator"!=}{weak_ordering}% +\indexlibrarymember{operator<}{weak_ordering}% +\indexlibrarymember{operator<=}{weak_ordering}% +\indexlibrarymember{operator>}{weak_ordering}% +\indexlibrarymember{operator>=}{weak_ordering}% +\begin{itemdecl} +constexpr bool operator==(weak_ordering v, @\unspec@) noexcept; +constexpr bool operator!=(weak_ordering v, @\unspec@) noexcept; +constexpr bool operator< (weak_ordering v, @\unspec@) noexcept; +constexpr bool operator<=(weak_ordering v, @\unspec@) noexcept; +constexpr bool operator> (weak_ordering v, @\unspec@) noexcept; +constexpr bool operator>=(weak_ordering v, @\unspec@) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value @ 0} for \tcode{operator@}. +\end{itemdescr} + +\indexlibrarymember{operator==}{weak_ordering}% +\indexlibrarymember{operator"!=}{weak_ordering}% +\indexlibrarymember{operator<}{weak_ordering}% +\indexlibrarymember{operator<=}{weak_ordering}% +\indexlibrarymember{operator>}{weak_ordering}% +\indexlibrarymember{operator>=}{weak_ordering}% +\begin{itemdecl} +constexpr bool operator==(@\unspec@, weak_ordering v) noexcept; +constexpr bool operator!=(@\unspec@, weak_ordering v) noexcept; +constexpr bool operator< (@\unspec@, weak_ordering v) noexcept; +constexpr bool operator<=(@\unspec@, weak_ordering v) noexcept; +constexpr bool operator> (@\unspec@, weak_ordering v) noexcept; +constexpr bool operator>=(@\unspec@, weak_ordering v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{0 @ v.value} for \tcode{operator@}. +\end{itemdescr} + +\rSec3[cmp.strongord]{Class \tcode{strong_ordering}} + +\pnum +The \tcode{strong_ordering} type is typically used +as the result type of a three-way comparison operator\iref{expr.spaceship} +that (a) admits all of the six two-way comparison operators (\ref{expr.rel}, \ref{expr.eq}), +and (b) does imply substitutability. + +\indexlibrary{\idxcode{strong_ordering}}% +\indexlibrarymember{less}{strong_ordering}% +\indexlibrarymember{equal}{strong_ordering}% +\indexlibrarymember{equivalent}{strong_ordering}% +\indexlibrarymember{greater}{strong_ordering}% +\begin{codeblock} +namespace std { + class strong_ordering { + 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 + + public: + // valid values + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + constexpr operator weak_equality() const noexcept; + constexpr operator strong_equality() const noexcept; + constexpr operator partial_ordering() const noexcept; + constexpr operator weak_ordering() const noexcept; + + // comparisons + friend constexpr bool operator==(strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator!=(strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator< (strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator<=(strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator> (strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator>=(strong_ordering v, @\unspec@) noexcept; + friend constexpr bool operator==(@\unspec@, strong_ordering v) noexcept; + friend constexpr bool operator!=(@\unspec@, strong_ordering v) noexcept; + friend constexpr bool operator< (@\unspec@, strong_ordering v) noexcept; + friend constexpr bool operator<=(@\unspec@, strong_ordering v) noexcept; + friend constexpr bool operator> (@\unspec@, strong_ordering v) noexcept; + friend constexpr bool operator>=(@\unspec@, strong_ordering v) noexcept; + }; + + // valid values' definitions + inline constexpr strong_ordering strong_ordering::less(ord::less); + inline constexpr strong_ordering strong_ordering::equal(eq::equal); + inline constexpr strong_ordering strong_ordering::equivalent(eq::equivalent); + inline constexpr strong_ordering strong_ordering::greater(ord::greater); +} +\end{codeblock} + +\indexlibrarymember{operator weak_equality}{strong_ordering}% +\begin{itemdecl} +constexpr operator weak_equality() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{value == 0 ?\ weak_equality::equivalent :\ weak_equality::nonequivalent}. +\end{itemdescr} + +\indexlibrarymember{operator strong_equality}{strong_ordering}% +\begin{itemdecl} +constexpr operator strong_equality() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{value == 0 ?\ strong_equality::equal :\ strong_equality::nonequal}. +\end{itemdescr} + +\indexlibrarymember{operator partial_ordering}{strong_ordering}% +\begin{itemdecl} +constexpr operator partial_ordering() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +value == 0 ? partial_ordering::equivalent : +value < 0 ? partial_ordering::less : + partial_ordering::greater +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator weak_ordering}{strong_ordering}% +\begin{itemdecl} +constexpr operator weak_ordering() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +value == 0 ? weak_ordering::equivalent : +value < 0 ? weak_ordering::less : + weak_ordering::greater +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator==}{strong_ordering}% +\indexlibrarymember{operator"!=}{strong_ordering}% +\indexlibrarymember{operator<}{strong_ordering}% +\indexlibrarymember{operator<=}{strong_ordering}% +\indexlibrarymember{operator>}{strong_ordering}% +\indexlibrarymember{operator>=}{strong_ordering}% +\begin{itemdecl} +constexpr bool operator==(strong_ordering v, @\unspec@) noexcept; +constexpr bool operator!=(strong_ordering v, @\unspec@) noexcept; +constexpr bool operator< (strong_ordering v, @\unspec@) noexcept; +constexpr bool operator<=(strong_ordering v, @\unspec@) noexcept; +constexpr bool operator> (strong_ordering v, @\unspec@) noexcept; +constexpr bool operator>=(strong_ordering v, @\unspec@) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{v.value @ 0} for \tcode{operator@}. +\end{itemdescr} + +\indexlibrarymember{operator==}{strong_ordering}% +\indexlibrarymember{operator"!=}{strong_ordering}% +\indexlibrarymember{operator<}{strong_ordering}% +\indexlibrarymember{operator<=}{strong_ordering}% +\indexlibrarymember{operator>}{strong_ordering}% +\indexlibrarymember{operator>=}{strong_ordering}% +\begin{itemdecl} +constexpr bool operator==(@\unspec@, strong_ordering v) noexcept; +constexpr bool operator!=(@\unspec@, strong_ordering v) noexcept; +constexpr bool operator< (@\unspec@, strong_ordering v) noexcept; +constexpr bool operator<=(@\unspec@, strong_ordering v) noexcept; +constexpr bool operator> (@\unspec@, strong_ordering v) noexcept; +constexpr bool operator>=(@\unspec@, strong_ordering v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{0 @ v.value} for \tcode{operator@}. +\end{itemdescr} + +\rSec2[cmp.common]{Class template \tcode{common_comparison_category}} + +\pnum +The type \tcode{common_comparison_category} provides an alias for +the strongest comparison category +to which all of the template arguments can be converted. +\begin{note} +A comparison category type is stronger than another if +they are distinct types and an instance of the former +can be converted to an instance of the latter. +\end{note} + +\indexlibrary{\idxcode{common_comparison_category}}% +\begin{itemdecl} +template +struct common_comparison_category { + using type = @\seebelow@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +The member \grammarterm{typedef-name} \tcode{type} denotes +the common comparison type\iref{class.spaceship} of \tcode{Ts...}, +the expanded parameter pack. +\begin{note} +This is well-defined even if +the expansion is empty or +includes a type that is not a comparison category type. +\end{note} +\end{itemdescr} + +\rSec2[cmp.alg]{Comparison algorithms} + +\indexlibrary{\idxcode{strong_order}}% +\begin{itemdecl} +template constexpr strong_ordering strong_order(const T& a, const T& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of type \tcode{strong_ordering}: + +\begin{itemize} +\item +If \tcode{numeric_limits::is_iec559} is \tcode{true}, +returns a result of type \tcode{strong_ordering} +that is consistent with the \tcode{totalOrder} operation +as specified in ISO/IEC/IEEE 60559. +\item +Otherwise, returns \tcode{a <=> b} +if that expression is well-formed and +convertible to \tcode{strong_ordering}. +\item +Otherwise, if the expression \tcode{a <=> b} is well-formed, +then the function is defined as deleted. +\item +Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} +are each well-formed and convertible to \tcode{bool}, then +\begin{itemize} +\item +if \tcode{a == b} is \tcode{true}, +returns \tcode{strong_ordering::equal}; +\item +otherwise, if \tcode{a < b} is \tcode{true}, +returns \tcode{strong_ordering::less}; +\item +otherwise, +returns \tcode{strong_ordering::greater}. +\end{itemize} +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{weak_order}}% +\begin{itemdecl} +template constexpr weak_ordering weak_order(const T& a, const T& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of type \tcode{weak_ordering}: + +\begin{itemize} +\item +Returns \tcode{a <=> b} if that expression is well-formed and +convertible to \tcode{weak_ordering}. +\item +Otherwise, if the expression \tcode{a <=> b} is well-formed, +then the function is defined as deleted. +\item +Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} +are each well-formed and convertible to \tcode{bool}, then +\begin{itemize} +\item +if \tcode{a == b} is \tcode{true}, +returns \tcode{weak_ordering::equivalent}; +\item +otherwise, if \tcode{a < b} is \tcode{true}, +returns \tcode{weak_ordering::less}; +\item +otherwise, returns \tcode{weak_ordering::greater}. +\end{itemize} +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{partial_order}}% +\begin{itemdecl} +template constexpr partial_ordering partial_order(const T& a, const T& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of type \tcode{partial_ordering}: + +\begin{itemize} +\item +Returns \tcode{a <=> b} if that expression is well-formed and +convertible to \tcode{partial_ordering}. +\item +Otherwise, if the expression \tcode{a <=> b} is well-formed, +then the function is defined as deleted. +\item +Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} +are each well-formed and convertible to \tcode{bool}, then +\begin{itemize} +\item +if \tcode{a == b} is \tcode{true}, +returns \tcode{partial_ordering::equivalent}; +\item +otherwise, if \tcode{a < b is true}, +returns \tcode{partial_ordering::less}; +\item +otherwise, returns \tcode{partial_ordering::greater}. +\end{itemize} +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{strong_equal}}% +\begin{itemdecl} +template constexpr strong_equality strong_equal(const T& a, const T& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of type \tcode{strong_equality}: + +\begin{itemize} +\item +Returns \tcode{a <=> b} if that expression is well-formed and +convertible to \tcode{strong_equality}. +\item +Otherwise, if the expression \tcode{a <=> b} is well-formed, +then the function is defined as deleted. +\item +Otherwise, if the expression \tcode{a == b} +is well-formed and convertible to \tcode{bool}, then +\begin{itemize} +\item +if \tcode{a == b} is \tcode{true}, +returns \tcode{strong_equality::equal}; +\item +otherwise, returns \tcode{strong_equality::nonequal}. +\end{itemize} +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{weak_equal}}% +\begin{itemdecl} +template constexpr weak_equality weak_equal(const T& a, const T& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of type \tcode{weak_equality}: + +\begin{itemize} +\item +Returns \tcode{a <=> b} if that expression is well-formed and +convertible to \tcode{weak_equality}. +\item +Otherwise, if the expression \tcode{a <=> b} is well-formed, +then the function is defined as deleted. +\item +Otherwise, if the expression \tcode{a == b} +is well-formed and convertible to \tcode{bool}, then +\begin{itemize} +\item +if \tcode{a == b} is \tcode{true}, +returns \tcode{weak_equality::equivalent}; +\item +otherwise, returns \tcode{weak_equality::nonequivalent}. +\end{itemize} +\item +Otherwise, the function is defined as deleted. +\end{itemize} +\end{itemdescr} + \rSec1[support.runtime]{Other runtime support} \pnum -\indextext{\idxhdr{cstdarg}}% -\indexlibrary{\idxhdr{cstdarg}}% -\indextext{\idxhdr{csetjmp}}% -\indexlibrary{\idxhdr{csetjmp}}% -\indextext{\idxhdr{ctime}}% -\indexlibrary{\idxhdr{ctime}}% -\indextext{\idxhdr{csignal}}% -\indexlibrary{\idxhdr{csignal}}% -\indextext{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{cstdlib}}% +\indexhdr{cstdarg}% +\indexhdr{csetjmp}% +\indexhdr{ctime}% +\indexhdr{csignal}% +\indexhdr{cstdlib}% \indexlibrary{\idxcode{getenv}}% \indexlibrary{\idxcode{system}}% Headers @@ -3743,8 +4592,7 @@ \rSec2[cstdarg.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{cstdarg}}% -\indexlibrary{\idxhdr{cstdarg}}% +\indexhdr{cstdarg}% \indexlibrary{\idxcode{va_list}}% \indexlibrary{\idxcode{va_start}}% \indexlibrary{\idxcode{va_copy}}% @@ -3762,15 +4610,14 @@ \end{codeblock} \pnum -\indextext{\idxhdr{stdarg.h}}% -\indexlibrary{\idxhdr{stdarg.h}}% +\indexhdr{stdarg.h}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}, with the following changes: The restrictions that ISO C places on the second parameter to the \indexlibrary{\idxcode{va_start}}% \tcode{va_start} macro in header -\indexlibrary{\idxhdr{stdarg.h}}% +\indexhdr{stdarg.h}% \tcode{} are different in this document. The parameter @@ -3796,8 +4643,7 @@ \rSec2[csetjmp.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{csetjmp}}% -\indexlibrary{\idxhdr{csetjmp}}% +\indexhdr{csetjmp}% \indexlibrary{\idxcode{jmp_buf}}% \indexlibrary{\idxcode{longjmp}}% \indexlibrary{\idxcode{setjmp}}% @@ -3811,8 +4657,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{setjmp.h}}% -\indexlibrary{\idxhdr{setjmp.h}}% +\indexhdr{setjmp.h}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}. @@ -3830,8 +4675,7 @@ \rSec2[csignal.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{csignal}}% -\indexlibrary{\idxhdr{csignal}}% +\indexhdr{csignal}% \indexlibrary{\idxcode{sig_atomic_t}}% \indexlibrary{\idxcode{signal}}% \indexlibrary{\idxcode{raise}}% @@ -3867,8 +4711,7 @@ \end{codeblock} \pnum -\indextext{\idxhdr{signal.h}}% -\indexlibrary{\idxhdr{signal.h}}% +\indexhdr{signal.h}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}. diff --git a/source/templates.tex b/source/templates.tex index 04245bb9fb..1e5a934e1a 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -21,7 +21,7 @@ \begin{bnf} \nontermdef{template-head}\br - \terminal{template} \terminal{<} template-parameter-list \terminal{>} requires-clause\opt + \terminal{template} \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause} \end{bnf} \begin{bnf} @@ -244,10 +244,10 @@ \begin{bnf} \nontermdef{type-parameter}\br - type-parameter-key \terminal{...}\opt identifier\opt\br - type-parameter-key identifier\opt{} \terminal{=} type-id\br - \terminal{template <} template-parameter-list \terminal{>} type-parameter-key \terminal{...}\opt identifier\opt\br - \terminal{template <} template-parameter-list \terminal{>} type-parameter-key identifier\opt{} \terminal{=} id-expression + type-parameter-key \opt{\terminal{...}} \opt{identifier}\br + type-parameter-key \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} \begin{bnf} @@ -258,19 +258,19 @@ \begin{bnf} \nontermdef{constrained-parameter}\br - qualified-concept-name \terminal{...} identifier\opt\br - qualified-concept-name identifier\opt{} default-template-argument\opt + 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 - nested-name-specifier\opt{} concept-name\br - nested-name-specifier\opt{} partial-concept-id + \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{<} template-argument-list\opt{} \terminal{>} + concept-name \terminal{<} \opt{template-argument-list} \terminal{>} \end{bnf} \begin{bnf} @@ -771,14 +771,14 @@ \begin{bnf} \nontermdef{simple-template-id}\br - template-name \terminal{<} template-argument-list\opt{} \terminal{>} + template-name \terminal{<} \opt{template-argument-list} \terminal{>} \end{bnf} \begin{bnf} \nontermdef{template-id}\br simple-template-id\br - operator-function-id \terminal{<} template-argument-list\opt{} \terminal{>}\br - literal-operator-id \terminal{<} template-argument-list\opt{} \terminal{>} + operator-function-id \terminal{<} \opt{template-argument-list} \terminal{>}\br + literal-operator-id \terminal{<} \opt{template-argument-list} \terminal{>} \end{bnf} \begin{bnf} @@ -788,8 +788,8 @@ \begin{bnf} \nontermdef{template-argument-list}\br - template-argument \terminal{...}\opt\br - template-argument-list \terminal{,} template-argument \terminal{...}\opt + template-argument \opt{\terminal{...}}\br + template-argument-list \terminal{,} template-argument \opt{\terminal{...}} \end{bnf} \begin{bnf} @@ -810,18 +810,27 @@ For a \grammarterm{template-name} to be explicitly qualified by the template arguments, -the name must be known to refer to a template. +the name must be considered to refer to a template. +\begin{note} +Whether a name actually refers to a template +cannot be known in some cases +until after argument dependent lookup is done\iref{basic.lookup.argdep}. +\end{note} +A name is considered to refer to a template if +name lookup finds +a \grammarterm{template-name} +or an overload set that contains a function template. +A name is also considered to refer to a template if +it is an \grammarterm{unqualified-id} +followed by a \tcode{<} +and name lookup finds either one or more functions or finds nothing. \pnum \indextext{\idxcode{<}!template and}% -After name lookup\iref{basic.lookup} finds that a name is a -\grammarterm{template-name} -or that an \grammarterm{operator-function-id} or a \grammarterm{literal-operator-id} refers to a set of -overloaded functions any member of which is a function template, -if this is followed by a -\tcode{<}, -the -\tcode{<} +When a name is considered to be a +\grammarterm{template-name}, +and it is followed by a \tcode{<}, +the \tcode{<} is always taken as the delimiter of a \grammarterm{template-argument-list} and never as the less-than operator. @@ -841,7 +850,7 @@ the \grammarterm{template-id}. \begin{note} The second \tcode{>} token produced by this replacement rule may terminate an enclosing \grammarterm{template-id} construct or it may be part of a different -construct (e.g. a cast).\end{note} +construct (e.g., a cast).\end{note} \begin{example} \begin{codeblock} @@ -1167,9 +1176,9 @@ template specialization, the program is ill-formed. \pnum -When the template in a +When name lookup for the name in a \grammarterm{template-id} -is an overloaded function template, both non-template functions in the overload +finds an overload set, both non-template functions in the overload set and function templates in the overload set for which the \grammarterm{template-argument}{s} @@ -1412,14 +1421,14 @@ If \tcode{P} contains a parameter pack, then \tcode{A} also matches \tcode{P} if each of \tcode{A}'s template parameters matches the corresponding template parameter in the -\grammarterm{template-parameter-list} of \tcode{P}. +\grammarterm{template-head} of \tcode{P}. Two template parameters match if they are of the same kind (type, non-type, template), for non-type \grammarterm{template-parameter}{s}, their types are equivalent\iref{temp.over.link}, and for template \grammarterm{template-parameter}{s}, each of their corresponding \grammarterm{template-parameter}{s} matches, recursively. -When \tcode{P}'s \grammarterm{template-parameter-list} contains a template parameter +When \tcode{P}'s \grammarterm{template-head} contains a template parameter pack\iref{temp.variadic}, the template parameter pack will match zero or more template -parameters or template parameter packs in the \grammarterm{template-parameter-list} of +parameters or template parameter packs in the \grammarterm{template-head} of \tcode{A} with the same type and form as the template parameter pack in \tcode{P} (ignoring whether those template parameters are template parameter packs). @@ -1489,11 +1498,13 @@ according to the partial ordering rules for function templates\iref{temp.func.order}. Given an invented class template \tcode{X} -with the template parameter list of \tcode{A} (including default arguments): +with the \grammarterm{template-head} of \tcode{A} (including default arguments +and \grammarterm{requires-clause}, if any): \begin{itemize} \item -Each of the two function templates has the same template parameters, +Each of the two function templates has the same template parameters +and \grammarterm{requires-clause} (if any), respectively, as \tcode{P} or \tcode{A}. \item Each function template has a single function parameter @@ -1501,7 +1512,7 @@ with template arguments corresponding to the template parameters from the respective function template where, for each template parameter \tcode{PP} -in the template parameter list of the function template, +in the \grammarterm{template-head} of the function template, a corresponding template argument \tcode{AA} is formed. If \tcode{PP} declares a parameter pack, then \tcode{AA} is the pack expansion \tcode{PP...}\iref{temp.variadic}; @@ -1514,7 +1525,7 @@ \pnum \begin{note} -This section defines the meaning of constraints on template arguments. +This subclause defines the meaning of constraints on template arguments. The abstract syntax and satisfaction rules are defined in \ref{temp.constr.constr}. Constraints are associated with declarations in \ref{temp.constr.decl}. @@ -1555,7 +1566,7 @@ There are two binary logical operations on constraints: conjunction and disjunction. \begin{note} -These logical operations have no corresponding \Cpp syntax. +These logical operations have no corresponding \Cpp{} syntax. For the purpose of exposition, conjunction is spelled using the symbol $\land$ and disjunction is spelled using the symbol $\lor$. @@ -1624,7 +1635,7 @@ \pnum Two atomic constraints are -\indextext{identical!atomic constraints|see{atomic constraint!identical}}% +\indextext{identical!atomic constraints|see{atomic constraint, identical}}% \defnx{identical}{atomic constraint!identical} if they are formed from the same \grammarterm{expression} @@ -1850,50 +1861,34 @@ \indextext{subsume|see{constraint, subsumption}} \pnum -A constraint $P$ is said to subsume another constraint $Q$ -if it can be determined that $P$ implies $Q$, up to -the identity\iref{temp.constr.atomic} -of atomic constraints in $P$ and $Q$, -as described below. -\begin{example} -Subsumption does not determine if the atomic constraint -\tcode{N >= 0}\iref{temp.constr.atomic} subsumes \tcode{N > 0} for some -integral template argument \tcode{N}. -\end{example} - -\pnum -In order to determine if a constraint $P$ subsumes a constraint $Q$, -$P$ is transformed into disjunctive normal form, and -$Q$ is transformed into conjunctive normal form.\footnote{% +A constraint $P$ \defnx{subsumes}{constraint!subsumption} a constraint $Q$ +if and only if, +for every disjunctive clause $P_i$ +in the disjunctive normal form\footnote{ A constraint is in disjunctive normal form when it is a disjunction of clauses where each clause is a conjunction of atomic constraints. -% -Similarly, a constraint is in conjunctive normal form when it is a conjunction -of clauses where each clause is a disjunction of atomic constraints. -% \begin{example} -Let $A$, $B$, and $C$ be atomic constraints, which can be grouped -using parentheses. -% -The constraint $A \land (B \lor C)$ is in -conjunctive normal form. -% -Its conjunctive clauses are $A$ and $(B \lor C)$. -% -The disjunctive normal form of the constraint +For atomic constraints $A$, $B$, and $C$, the disjunctive normal form +of the constraint $A \land (B \lor C)$ is $(A \land B) \lor (A \land C)$. % -Its disjunctive clauses are $(A \land B)$ and -$(A \land C)$. +Its disjunctive clauses are $(A \land B)$ and $(A \land C)$. \end{example}% } +of $P$, $P_i$ subsumes every conjunctive clause $Q_j$ +in the conjuctive normal form\footnote{ +A constraint is in conjunctive normal form when it is a conjunction +of clauses where each clause is a disjunction of atomic constraints. +\begin{example} +For atomic constraints $A$, $B$, and $C$, the constraint +$A \land (B \lor C)$ is in conjunctive normal form. % -Then, $P$ \defnx{subsumes}{constraint!subsumption} $Q$ if and only if, -for every disjunctive clause $P_i$ in the disjunctive normal -form of $P$, $P_i$ subsumes every conjunctive clause $Q_j$ -in the conjuctive normal form of $Q$, where +Its conjunctive clauses are $A$ and $(B \lor C)$. +\end{example}% +} +of $Q$, where \begin{itemize} \item @@ -2898,20 +2893,23 @@ \end{example} \pnum -A member of a class template may be declared to be a friend of a -non-template class. +A template friend declaration may declare +a member of a dependent type to be a friend. +The friend declaration shall declare a function or +specify a type with an \grammarterm{elaborated-type-specifier}, +in either case with a \grammarterm{nested-name-specifier} +ending with a \grammarterm{simple-template-id}, \placeholder{C}, +whose \grammarterm{template-name} names a class template. +The template parameters of the template friend declaration +shall be deducible from \placeholder{C}~(\ref{temp.deduct.type}). In this case, -the corresponding member of every specialization of -the primary class template and -class template partial specializations thereof -is a friend of the class granting friendship. -For -explicit specializations and -specializations of partial specializations, -the corresponding member is the member (if any) -that has the same name, kind (type, function, class template, or function -template), template parameters, and signature as the member of the class -template instantiation that would otherwise have been generated. +a member of a specialization \placeholder{S} of the class template +is a friend of the class granting friendship +if deduction of the template parameters +of \placeholder{C} from \placeholder{S} succeeds, and +substituting the deduced template arguments into the friend declaration +produces a declaration that would be a valid redeclaration +of the member of the specialization. \begin{example} \begin{codeblock} @@ -2921,6 +2919,8 @@ struct D { void g(); }; + T h(); + template T i(); }; template<> struct A { struct B { }; @@ -2928,6 +2928,10 @@ struct D { void g(); }; + template int i(); +}; +template<> struct A { + int *h(); }; class C { @@ -2935,9 +2939,12 @@ // it is not a specialization of \tcode{A::B} template friend void A::f(); // does not grant friendship to \tcode{A::f()} // because its return type does not match - template friend void A::D::g(); // does not grant friendship to \tcode{A::D::g()} - // because \tcode{A::D} is not a specialization of \tcode{A::D} -}; + template friend void A::D::g(); // ill-formed: \tcode{A::D} does not end with + // a \grammarterm{simple-template-id} + template friend int *A::h(); // grants friendship to \tcode{A::h()} and \tcode{A::h()} + template template // grants friendship to instantiations of \tcode{A::i()} and + friend T A::i(); // to \tcode{A::i()}, and thereby to all specializations +}; // of those function templates \end{codeblock} \end{example} @@ -3150,6 +3157,17 @@ the last argument in the template argument list. \end{itemize} +\pnum +The usual access checking rules do not apply to non-dependent names +used to specify template arguments of the \grammarterm{simple-template-id} +of the partial specialization. +\begin{note} +The template arguments may be private types or +objects that would normally not be accessible. +Dependent names cannot be checked when declaring the partial specialization, +but will be checked when substituting into the partial specialization. +\end{note} + \rSec3[temp.class.spec.match]{Matching of class template partial specializations} \pnum @@ -3516,14 +3534,18 @@ the one-definition rule\iref{basic.def.odr}, except that the tokens used to name the template parameters may differ as long as a token used to name a template parameter in one expression is replaced by another token -that names the same template parameter in the other expression. For -determining whether two dependent names\iref{temp.dep} are +that names the same template parameter in the other expression. +Two \grammarterm{lambda-expression}{s} are never considered equivalent. +\begin{note} +The intent is to avoid \grammarterm{lambda-expression}{s} appearing in the +signature of a function template with external linkage. +\end{note} +For determining whether two dependent names\iref{temp.dep} are equivalent, only the name itself is considered, not the result of name lookup in the context of the template. If multiple declarations of the same function template differ in the result of this name lookup, the result for the first declaration is used. \begin{example} - \begin{codeblock} template void f(A); // \#1 template void f(A); // same as \#1 @@ -3534,6 +3556,14 @@ { return g(T()); } // \ldots{} although the lookup here does find \tcode{g(int)} int i = h(); // template argument substitution fails; \tcode{g(int)} // was not in scope at the first declaration of \tcode{h()} + +// ill-formed, no diagnostic required: the two expressions are functionally equivalent but not equivalent +template void foo(const char (*s)[([]{}, N)]); +template void foo(const char (*s)[([]{}, N)]); + +// two different declarations because the non-dependent portions are not considered equivalent +template void spam(decltype([]{}) (*s)[sizeof(T)]); +template void spam(decltype([]{}) (*s)[sizeof(T)]); \end{codeblock} \end{example} \indextext{expression!functionally equivalent|see{functionally equivalent, expressions}}% @@ -3587,7 +3617,7 @@ expressions involving template parameters. \indextext{equivalent!functionally|see{functionally equivalent}}% -\indextext{template!function!functionally equivalent|see{functionally equivalent!function template}}% +\indextext{template!function!functionally equivalent|see{functionally equivalent, function template}}% Two function templates are \defnx{functionally equivalent}{functionally equivalent!function templates} if they @@ -3867,6 +3897,17 @@ \end{codeblock} \end{example} +\pnum +The type of a lambda expression appearing in an alias template declaration +is different between instantiations of that template, even when the lambda +expression is not dependent. +\begin{example} +\begin{codeblock} +template + using A = decltype([] { }); // \tcode{A} and \tcode{A} refer to different closure types +\end{codeblock} +\end{example} + \rSec2[temp.concept]{Concept definitions} \pnum @@ -3990,7 +4031,7 @@ \begin{bnf} \nontermdef{typename-specifier}\br \terminal{typename} nested-name-specifier identifier\br - \terminal{typename} nested-name-specifier \terminal{template\opt} simple-template-id + \terminal{typename} nested-name-specifier \terminal{\opt{template}} simple-template-id \end{bnf} \pnum @@ -4148,7 +4189,7 @@ \item constant expression evaluation\iref{expr.const} within the template instantiation uses \begin{itemize} - \item the value of a \tcode{const} object of integral or unscoped enumeration type or + \item the value of a const object of integral or unscoped enumeration type or \item the value of a \tcode{constexpr} object or \item the value of a reference or \item the definition of a constexpr function, @@ -4513,7 +4554,7 @@ In an expression of the form: \begin{ncbnftab} -postfix-expression \terminal{(} expression-list\opt{} \terminal{)} +postfix-expression \terminal{(} \opt{expression-list} \terminal{)} \end{ncbnftab} where the @@ -4683,14 +4724,27 @@ \pnum A template argument that is equivalent to a template -parameter (i.e., has the same constant value or the same type -as the template parameter) can be used in place of that -template parameter in a reference to the current -instantiation. In the case of a non-type template argument, -this only applies if -the argument was given the value of the -template parameter and not an expression in which the -template parameter appears as a subexpression. +parameter can be used in place of that +template parameter in a reference to the current instantiation. +For a template \grammarterm{type-parameter}, +a template argument is equivalent to a template parameter +if it denotes the same type. +For a non-type template parameter, +a template argument is equivalent to a template parameter +if it is an \grammarterm{identifier} that names a variable +that is equivalent to the template parameter. +A variable is equivalent to a template parameter if +\begin{itemize} +\item + it has the same type as the template parameter + (ignoring cv-qualification) and +\item + its initializer consists of a single \grammarterm{identifier} + that names the template parameter or, recursively, such a variable. +\end{itemize} +\begin{note} +Using a parenthesized variable name breaks the equivalence. +\end{note} \begin{example} \begin{codeblock} template class A { @@ -4717,9 +4771,13 @@ static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; + static const long my_I4 = I; + static const int my_I5 = (I); B* b3; // refers to the current instantiation B* b4; // not the current instantiation B* b5; // refers to the current instantiation + B* b6; // not the current instantiation + B* b7; // not the current instantiation }; \end{codeblock} \end{example} @@ -5012,9 +5070,9 @@ is dependent, even if any subexpression is type-dependent: \begin{ncbnftab} -simple-type-specifier \terminal{(} expression-list\opt{} \terminal{)}\br -\terminal{::\opt new} new-placement\opt new-type-id new-initializer\opt\br -\terminal{::\opt new} new-placement\opt{} \terminal{(} type-id \terminal{)} new-initializer\opt\br +simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +\terminal{\opt{::} new} \opt{new-placement} new-type-id \opt{new-initializer}\br +\terminal{\opt{::} new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer}\br \terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br \terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br \terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br @@ -5036,9 +5094,9 @@ \terminal{alignof (} type-id \terminal{)}\br \terminal{typeid (} expression \terminal{)}\br \terminal{typeid (} type-id \terminal{)}\br -\terminal{::\opt delete} cast-expression\br -\terminal{::\opt delete [ ]} cast-expression\br -\terminal{throw} assignment-expression\opt\br +\terminal{\opt{::} delete} cast-expression\br +\terminal{\opt{::} delete [ ]} cast-expression\br +\terminal{throw} \opt{assignment-expression}\br \terminal{noexcept} \terminal{(} expression \terminal{)} \end{ncbnftab} @@ -5143,7 +5201,7 @@ is value-dependent: \begin{ncbnftab} -simple-type-specifier \terminal{(} expression-list\opt{} \terminal{)}\br +simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br \terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br \terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br \terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br @@ -5460,6 +5518,19 @@ \end{itemize} An implementation is not required to diagnose a violation of this rule. +\pnum +The usual access checking rules do not apply to names +in a declaration of an explicit instantiation or explicit specialization, +with the exception of names appearing in a function body, +default argument, base-clause, member-specification, enumerator-list, +or static data member or variable template initializer. +\begin{note} +In particular, the template arguments and names +used in the function declarator +(including parameter types, return types and exception specifications) +may be private types or objects that would normally not be accessible. +\end{note} + \pnum Each class template specialization instantiated from a template has its own copy of any static members. @@ -5607,7 +5678,9 @@ instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition -to exist; +to exist or +if the existence of the definition of the member +affects the semantics of the program; in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist. @@ -5617,10 +5690,12 @@ explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition -to exist. +to exist or +if the existence of the definition affects the semantics of the program. A function whose declaration was instantiated from a friend function definition is implicitly instantiated when it is referenced in a context that -requires a function definition to exist. +requires a function definition to exist or +if the existence of the definition affects the semantics of the program. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a @@ -5657,10 +5732,41 @@ \pnum Unless a variable template specialization has been explicitly instantiated or -explicitly specialized, the variable template specialization is implicitly -instantiated when the specialization is used. A default template argument for a -variable template is implicitly instantiated when the variable template is -referenced in a context that requires the value of the default argument. +explicitly specialized, +the variable template specialization is implicitly instantiated +when it is referenced in a context +that requires a variable definition to exist or +if the existence of the definition affects the semantics of the program. +A default template argument for a variable template is implicitly instantiated +when the variable template is referenced in a context +that requires the value of the default argument. + +\pnum +\indextext{definition!program semantics affected by}% +\indextext{variable!program semantics affected by the existence of a variable definition}% +\indextext{function!program semantics affected by the existence of a function definition}% +\indextext{program semantics!affected by the existence of a variable or function definition}% +The existence of a definition of a variable or function +is considered to affect the semantics of the program +if the variable or function +is needed for constant evaluation by an expression\iref{expr.const}, +even if constant evaluation of the expression is not required or +if constant expression evaluation does not use the definition. + +\begin{example} +\begin{codeblock} +template constexpr int f() { return T::value; } +template void g(decltype(B ? f() : 0)); +template void g(...); +template void h(decltype(int{B ? f() : 0})); +template void h(...); +void x() { + g(0); // OK, \tcode{B ? f() : 0} is not potentially constant evaluated + h(0); // error, instantiates \tcode{f} even though \tcode{B} evaluates to \tcode{false} and + // list-initialization of \tcode{int} from \tcode{int} cannot be narrowing +} +\end{codeblock} +\end{example} \pnum If the function selected by overload resolution\iref{over.match} @@ -5695,6 +5801,13 @@ a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement\iref{stmt.if}, unless such instantiation is required. +\begin{note} +The instantiation of a generic lambda +does not require instantiation of +substatements of a constexpr if statement +within its \grammarterm{compound-statement} +unless the call operator template is instantiated. +\end{note} It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated. @@ -5875,8 +5988,11 @@ instantiated from its template. A member function, member class or static data member of a class template can be explicitly instantiated from the member definition associated with its class -template. An explicit instantiation of a function template -or member function of a class template +template. +An explicit instantiation of a +function template, +member function of a class template, or +variable template shall not use the \tcode{inline} or \tcode{constexpr} specifiers. @@ -5885,7 +6001,7 @@ \begin{bnf} \nontermdef{explicit-instantiation}\br - \terminal{extern\opt} \terminal{template} declaration + \terminal{\opt{extern}} \terminal{template} declaration \end{bnf} There are two forms of explicit instantiation: an explicit instantiation @@ -6106,19 +6222,6 @@ An explicit instantiation declaration shall not name a specialization of a template with internal linkage. - - -\pnum -The usual access checking rules do not apply to names used to specify -explicit instantiations. -\begin{note} -In particular, the template arguments and names used in the function -declarator (including parameter types, return types and exception -specifications) may be private types or objects which would normally -not be accessible and the template may be a member template or member -function which would not normally be accessible. -\end{note} - \pnum An explicit instantiation does not constitute a use of a default argument, so default argument instantiation is not done. @@ -6786,45 +6889,6 @@ function name, there is no way to provide an explicit template argument list for these function templates. \end{note} -% L7048 USA Core3 1.18 / 14.8.1 [temp.arg.explicit] -% WG21 decided not to address this issue except to document that -% argument-dependent lookup does not apply in this context. - -\pnum -\begin{note} -For simple function names, argument dependent lookup\iref{basic.lookup.argdep} -applies even when the function name is not visible within the scope of the call. -This is because the call still has the syntactic form of a function call\iref{basic.lookup.unqual}. -But when a function template with explicit template arguments is used, -the call does not have the correct syntactic form unless there is a function -template with that name visible at the point of the call. -If no such name is visible, -the call is not syntactically well-formed and argument-dependent lookup -does not apply. -If some such name is visible, -argument dependent lookup applies and additional function templates -may be found in other namespaces. -\begin{example} - -% Argument added to f per Usenet posting from martin von Loewis, 6 Sep 1998 -\begin{codeblock} -namespace A { - struct B { }; - template void f(B); -} -namespace C { - template void f(T t); -} -void g(A::B b) { - f<3>(b); // ill-formed: not a function call - A::f<3>(b); // well-formed - C::f<3>(b); // ill-formed; argument dependent lookup applies only to unqualified names - using C::f; - f<3>(b); // well-formed because \tcode{C::f} is visible; then \tcode{A::f} is found by argument dependent lookup -} -\end{codeblock} -\end{example} -\end{note} \pnum Template argument deduction can extend the sequence of template @@ -7030,6 +7094,43 @@ program being ill-formed. \end{note} +\pnum +A \grammarterm{lambda-expression} appearing in a function type +or a template parameter is not considered part of the immediate context +for the purposes of template argument deduction. +\begin{note} +The intent is to avoid requiring implementations to deal with +substitution failure involving arbitrary statements. +\begin{example} +\begin{codeblock} +template + auto f(T) -> decltype([]() { T::invalid; } ()); +void f(...); +f(0); // error: invalid expression not part of the immediate context + +template + void g(T); +void g(...); +g(0); // error: invalid expression not part of the immediate context + +template + auto h(T) -> decltype([x = T::invalid]() { }); +void h(...); +h(0); // error: invalid expression not part of the immediate context + +template + auto i(T) -> decltype([]() -> typename T::invalid { }); +void i(...); +i(0); // error: invalid expression not part of the immediate context + +template + auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // \#1 +void j(...); // \#2 +j(0); // deduction fails on \#1, calls \#2 +\end{codeblock} +\end{example} +\end{note} + \pnum \begin{example} \begin{codeblock} @@ -7359,7 +7460,7 @@ the transformed \tcode{A}. \item The transformed \tcode{A} -can be another pointer or pointer to member type that can be converted +can be another pointer or pointer-to-member type that can be converted to the deduced \tcode{A} via a function pointer conversion\iref{conv.fctptr} and/or @@ -7407,8 +7508,7 @@ \pnum When \tcode{P} -is a function type, function pointer type, or pointer to member -function type: +is a function type, function pointer type, or pointer-to-member-function type: \begin{itemize} \item If the argument is an overload set containing one or more function templates, @@ -7519,7 +7619,7 @@ \pnum If \tcode{P} is a reference type, the type referred to by \tcode{P} is used in place of \tcode{P} for type deduction and for any further references to or transformations of -\tcode{P} in the remainder of this section. +\tcode{P} in the remainder of this subclause. \pnum If @@ -7582,12 +7682,12 @@ \tcode{A} can be ``pointer to function'' even if the deduced \tcode{A} is ``pointer to noexcept function''. \item -If the original \tcode{A} is a pointer to member function type, +If the original \tcode{A} is a pointer-to-member-function type, \tcode{A} can be ``pointer to member of type function'' even if the deduced \tcode{A} is ``pointer to member of type noexcept function''. \item The deduced \tcode{A} -can be another pointer or pointer to member type that +can be another pointer or pointer-to-member type that can be converted to \tcode{A} via a qualification conversion. \end{itemize} @@ -7600,22 +7700,22 @@ \pnum When the deduction process requires a qualification conversion for a -pointer or pointer to member type as described above, the following +pointer or pointer-to-member type as described above, the following process is used to determine the deduced template argument values: If \tcode{A} is a type \begin{indented} -$\mathit{cv}_{1,0}$ ``pointer to $\ldots$'' $\mathit{cv}_{1,n-1}$ ``pointer to'' -$\mathit{cv}_{1,n}$ \tcode{T1} +$\text{\cv}_{1,0}$ ``pointer to $\ldots$'' $\text{\cv}_{1,n-1}$ ``pointer to'' +$\text{\cv}_{1,n}$ \tcode{T1} \end{indented} and \tcode{P} is a type \begin{indented} -$\mathit{cv}_{2,0}$ ``pointer to $\ldots$'' $\mathit{cv}_{2,n-1}$ ``pointer to'' -$\mathit{cv}_{2,n}$ \tcode{T2}, +$\text{\cv}_{2,0}$ ``pointer to $\ldots$'' $\text{\cv}_{2,n-1}$ ``pointer to'' +$\text{\cv}_{2,n}$ \tcode{T2}, \end{indented} then the cv-unqualified \tcode{T1} @@ -7902,7 +8002,7 @@ A function type includes the types of each of the function parameters and the return type. \item -A pointer to member type includes the type of the class object pointed to +A pointer-to-member type includes the type of the class object pointed to and the type of the member pointed to. \item A type that is a specialization of a class template (e.g., @@ -8421,8 +8521,8 @@ \pnum A \grammarterm{template-argument} -can be deduced from a function, pointer to function, or pointer to -member function type. +can be deduced from a function, pointer to function, or +pointer-to-member-function type. \begin{example} @@ -8673,7 +8773,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \terminal{explicit}\opt{} template-name \terminal{(} parameter-declaration-clause \terminal{) ->} simple-template-id \terminal{;} + \opt{\terminal{explicit}} template-name \terminal{(} parameter-declaration-clause \terminal{) ->} simple-template-id \terminal{;} \end{bnf} \pnum diff --git a/source/threads.tex b/source/threads.tex index 73c4042385..6442c5a3f4 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -82,7 +82,7 @@ $D_m$. The delay durations may vary from timeout to timeout, but in all cases shorter is better. \pnum -The member functions whose names end in \tcode{_for} take an argument that +The functions whose names end in \tcode{_for} take an argument that specifies a duration. These functions produce relative timeouts. Implementations should use a steady clock to measure time for these functions.\footnote{All implementations for which standard time units are meaningful must necessarily @@ -90,7 +90,7 @@ argument $D_t$, the real-time duration of the timeout is $D_t + D_i + D_m$. \pnum -The member functions whose names end in \tcode{_until} take an argument that specifies a time +The functions whose names end in \tcode{_until} take an argument that specifies a time point. These functions produce absolute timeouts. Implementations should use the clock specified in the time point to measure time for these functions. Given a clock time point argument $C_t$, the clock time point of the return from timeout should be $C_t + D_i + D_m$ @@ -99,13 +99,13 @@ \begin{itemize} \item -if $C_a > C_t$, the waiting function should wake as soon as possible, i.e. $C_a + D_i + D_m$, +if $C_a > C_t$, the waiting function should wake as soon as possible, i.e., $C_a + D_i + D_m$, since the timeout is already satisfied. \begin{note} This specification may result in the total duration of the wait decreasing when measured against a steady clock. \end{note} \item if $C_a \leq C_t$, the waiting function should not time out until \tcode{Clock::now()} returns a -time $C_n \geq C_t$, i.e. waking at $C_t + D_i + D_m$. \begin{note} When the clock is adjusted +time $C_n \geq C_t$, i.e., waking at $C_t + D_i + D_m$. \begin{note} When the clock is adjusted backwards, this specification may result in the total duration of the wait increasing when measured against a steady clock. When the clock is adjusted forwards, this specification may result in the total duration of the wait decreasing when measured against a steady clock. @@ -147,7 +147,7 @@ An \defn{execution agent} is an entity such as a thread that may perform work in parallel with other execution agents. \begin{note} Implementations or users may introduce other kinds of agents such as processes or thread-pool tasks. \end{note} The calling agent is determined by -context, e.g. the calling thread that contains the call, and so on. +context, e.g., the calling thread that contains the call, and so on. \pnum \begin{note} Some lockable objects are ``agent oblivious'' in that they work for any @@ -279,7 +279,7 @@ result, where \tcode{decay_copy} is defined as follows: \begin{codeblock} -template decay_t decay_copy(T&& v) +template decay_t decay_copy(T&& v) { return std::forward(v); } \end{codeblock} @@ -291,8 +291,7 @@ \end{note} \rSec2[thread.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{thread}}% -\indexlibrary{\idxhdr{thread}}% +\indexhdr{thread}% \begin{codeblock} namespace std { @@ -304,9 +303,9 @@ thread::id get_id() noexcept; void yield() noexcept; - template + template void sleep_until(const chrono::time_point& abs_time); - template + template void sleep_for(const chrono::duration& rel_time); } } @@ -331,20 +330,20 @@ namespace std { class thread { public: - // types: + // types class id; using native_handle_type = @\impdefnc@; // see~\ref{thread.req.native} - // construct/copy/destroy: + // construct/copy/destroy thread() noexcept; - template explicit thread(F&& f, Args&&... args); + template explicit thread(F&& f, Args&&... args); ~thread(); thread(const thread&) = delete; thread(thread&&) noexcept; thread& operator=(const thread&) = delete; thread& operator=(thread&&) noexcept; - // members: + // members void swap(thread&) noexcept; bool joinable() const noexcept; void join(); @@ -352,7 +351,7 @@ id get_id() const noexcept; native_handle_type native_handle(); // see~\ref{thread.req.native} - // static members: + // static members static unsigned int hardware_concurrency() noexcept; }; } @@ -380,9 +379,9 @@ basic_ostream& operator<<(basic_ostream& out, thread::id id); - // Hash support - template struct hash; - template <> struct hash; + // hash support + template struct hash; + template<> struct hash; } \end{codeblock} @@ -491,7 +490,7 @@ \indexlibrary{\idxcode{hash}!\idxcode{thread::id}}% \begin{itemdecl} -template <> struct hash; +template<> struct hash; \end{itemdecl} \begin{itemdescr} @@ -513,12 +512,12 @@ \indexlibrary{\idxcode{thread}!constructor}% \begin{itemdecl} -template explicit thread(F&& f, Args&&... args); +template explicit thread(F&& f, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\requires\ \tcode{F} and each \tcode{Ti} in \tcode{Args} shall satisfy the +\requires\ \tcode{F} and each $\tcode{T}_i$ in \tcode{Args} shall satisfy the \tcode{MoveConstructible} requirements. \tcode{% \placeholdernc{INVOKE}(\brk{}% @@ -725,7 +724,7 @@ \pnum \returns The number of hardware thread contexts. \begin{note} This value should only be considered to be a hint. \end{note} If this value is not computable or -well defined, an implementation should return 0. +well-defined, an implementation should return 0. \end{itemdescr} \rSec3[thread.thread.algorithm]{\tcode{thread} specialized algorithms} @@ -746,9 +745,9 @@ thread::id get_id() noexcept; void yield() noexcept; - template + template void sleep_until(const chrono::time_point& abs_time); - template + template void sleep_for(const chrono::duration& rel_time); } \end{codeblock} @@ -781,7 +780,7 @@ \indexlibrarymember{sleep_until}{this_thread}% \begin{itemdecl} -template +template void sleep_until(const chrono::time_point& abs_time); \end{itemdecl} @@ -799,7 +798,7 @@ \indexlibrarymember{sleep_for}{this_thread}% \begin{itemdecl} -template +template void sleep_for(const chrono::duration& rel_time); \end{itemdecl} @@ -818,13 +817,12 @@ \rSec1[thread.mutex]{Mutual exclusion} \pnum -This section provides mechanisms for mutual exclusion: mutexes, locks, and call +This subclause provides mechanisms for mutual exclusion: mutexes, locks, and call once. These mechanisms ease the production of race-free programs\iref{intro.multithread}. \rSec2[mutex.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{mutex}}% -\indexlibrary{\idxhdr{mutex}}% +\indexhdr{mutex}% \begin{codeblock} namespace std { @@ -841,15 +839,15 @@ inline constexpr try_to_lock_t try_to_lock { }; inline constexpr adopt_lock_t adopt_lock { }; - template class lock_guard; - template class scoped_lock; - template class unique_lock; + template class lock_guard; + template class scoped_lock; + template class unique_lock; - template + template void swap(unique_lock& x, unique_lock& y) noexcept; - template int try_lock(L1&, L2&, L3&...); - template void lock(L1&, L2&, L3&...); + template int try_lock(L1&, L2&, L3&...); + template void lock(L1&, L2&, L3&...); struct once_flag; @@ -859,15 +857,14 @@ \end{codeblock} \rSec2[shared_mutex.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{shared_mutex}}% -\indexlibrary{\idxhdr{shared_mutex}}% +\indexhdr{shared_mutex}% \begin{codeblock} namespace std { class shared_mutex; class shared_timed_mutex; - template class shared_lock; - template + template class shared_lock; + template void swap(shared_lock& x, shared_lock& y) noexcept; } \end{codeblock} @@ -890,7 +887,7 @@ The \defn{mutex types} are the standard library types \tcode{mutex}, \tcode{recursive_mutex}, \tcode{timed_mutex}, \tcode{recursive_timed_mutex}, \tcode{shared_mutex}, and \tcode{shared_timed_mutex}. -They shall meet the requirements set out in this section. In this description, \tcode{m} +They shall meet the requirements set out in this subclause. In this description, \tcode{m} denotes an object of a mutex type. \pnum @@ -1225,9 +1222,9 @@ void lock(); // blocking bool try_lock(); - template + template bool try_lock_for(const chrono::duration& rel_time); - template + template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); @@ -1276,9 +1273,9 @@ void lock(); // blocking bool try_lock() noexcept; - template + template bool try_lock_for(const chrono::duration& rel_time); - template + template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); @@ -1443,12 +1440,12 @@ shared_mutex(const shared_mutex&) = delete; shared_mutex& operator=(const shared_mutex&) = delete; - // Exclusive ownership + // exclusive ownership void lock(); // blocking bool try_lock(); void unlock(); - // Shared ownership + // shared ownership void lock_shared(); // blocking bool try_lock_shared(); void unlock_shared(); @@ -1578,21 +1575,21 @@ shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; - // Exclusive ownership + // exclusive ownership void lock(); // blocking bool try_lock(); - template + template bool try_lock_for(const chrono::duration& rel_time); - template + template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); - // Shared ownership + // shared ownership void lock_shared(); // blocking bool try_lock_shared(); - template + template bool try_lock_shared_for(const chrono::duration& rel_time); - template + template bool try_lock_shared_until(const chrono::time_point& abs_time); void unlock_shared(); }; @@ -1656,7 +1653,7 @@ \indexlibrary{\idxcode{lock_guard}}% \begin{codeblock} namespace std { - template + template class lock_guard { public: using mutex_type = Mutex; @@ -1671,8 +1668,6 @@ private: mutex_type& pm; // \expos }; - - template lock_guard(lock_guard) -> lock_guard; } \end{codeblock} @@ -1734,7 +1729,7 @@ \indexlibrary{\idxcode{scoped_lock}}% \begin{codeblock} namespace std { - template + template class scoped_lock { public: using mutex_type = Mutex; // If \tcode{MutexTypes...} consists of the single type \tcode{Mutex} @@ -1749,9 +1744,6 @@ private: tuple pm; // \expos }; - - template - scoped_lock(scoped_lock) -> scoped_lock; } \end{codeblock} @@ -1817,7 +1809,7 @@ \indexlibrary{\idxcode{unique_lock}}% \begin{codeblock} namespace std { - template + template class unique_lock { public: using mutex_type = Mutex; @@ -1828,9 +1820,9 @@ unique_lock(mutex_type& m, defer_lock_t) noexcept; unique_lock(mutex_type& m, try_to_lock_t); unique_lock(mutex_type& m, adopt_lock_t); - template + template unique_lock(mutex_type& m, const chrono::time_point& abs_time); - template + template unique_lock(mutex_type& m, const chrono::duration& rel_time); ~unique_lock(); @@ -1844,9 +1836,9 @@ void lock(); bool try_lock(); - template + template bool try_lock_for(const chrono::duration& rel_time); - template + template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); @@ -1865,9 +1857,7 @@ bool owns; // \expos }; - template unique_lock(unique_lock) -> unique_lock; - - template + template void swap(unique_lock& x, unique_lock& y) noexcept; } \end{codeblock} @@ -1977,7 +1967,7 @@ \indexlibrary{\idxcode{unique_lock}!constructor}% \begin{itemdecl} -template +template unique_lock(mutex_type& m, const chrono::time_point& abs_time); \end{itemdecl} @@ -1998,7 +1988,7 @@ \indexlibrary{\idxcode{unique_lock}!constructor}% \begin{itemdecl} -template +template unique_lock(mutex_type& m, const chrono::duration& rel_time); \end{itemdecl} @@ -2113,7 +2103,7 @@ \indexlibrarymember{try_lock_until}{unique_lock}% \begin{itemdecl} -template +template bool try_lock_until(const chrono::time_point& abs_time); \end{itemdecl} @@ -2147,7 +2137,7 @@ \indexlibrarymember{try_lock_for}{unique_lock}% \begin{itemdecl} -template +template bool try_lock_for(const chrono::duration& rel_time); \end{itemdecl} @@ -2220,7 +2210,7 @@ \indexlibrarymember{swap}{unique_lock}% \begin{itemdecl} -template +template void swap(unique_lock& x, unique_lock& y) noexcept; \end{itemdecl} @@ -2262,7 +2252,7 @@ \indexlibrary{\idxcode{shared_lock}}% \begin{codeblock} namespace std { - template + template class shared_lock { public: using mutex_type = Mutex; @@ -2273,9 +2263,9 @@ shared_lock(mutex_type& m, defer_lock_t) noexcept; shared_lock(mutex_type& m, try_to_lock_t); shared_lock(mutex_type& m, adopt_lock_t); - template + template shared_lock(mutex_type& m, const chrono::time_point& abs_time); - template + template shared_lock(mutex_type& m, const chrono::duration& rel_time); ~shared_lock(); @@ -2288,9 +2278,9 @@ // \ref{thread.lock.shared.locking}, locking void lock(); // blocking bool try_lock(); - template + template bool try_lock_for(const chrono::duration& rel_time); - template + template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); @@ -2308,9 +2298,7 @@ bool owns; // \expos }; - template shared_lock(shared_lock) -> shared_lock; - - template + template void swap(shared_lock& x, shared_lock& y) noexcept; } \end{codeblock} @@ -2411,7 +2399,7 @@ \indexlibrary{\idxcode{shared_lock}!constructor}% \begin{itemdecl} -template +template shared_lock(mutex_type& m, const chrono::time_point& abs_time); \end{itemdecl} @@ -2432,7 +2420,7 @@ \indexlibrary{\idxcode{shared_lock}!constructor}% \begin{itemdecl} -template +template shared_lock(mutex_type& m, const chrono::duration& rel_time); \end{itemdecl} @@ -2546,7 +2534,7 @@ \indexlibrarymember{try_lock_until}{shared_lock}% \begin{itemdecl} -template +template bool try_lock_until(const chrono::time_point& abs_time); \end{itemdecl} @@ -2577,7 +2565,7 @@ \indexlibrarymember{try_lock_for}{shared_lock}% \begin{itemdecl} -template +template bool try_lock_for(const chrono::duration& rel_time); \end{itemdecl} @@ -2653,7 +2641,7 @@ \indexlibrarymember{swap}{shared_lock}% \begin{itemdecl} -template +template void swap(shared_lock& x, shared_lock& y) noexcept; \end{itemdecl} @@ -2698,7 +2686,7 @@ \indexlibrary{\idxcode{try_lock}}% \begin{itemdecl} -template int try_lock(L1&, L2&, L3&...); +template int try_lock(L1&, L2&, L3&...); \end{itemdecl} \begin{itemdescr} @@ -2722,7 +2710,7 @@ \indexlibrary{\idxcode{lock}}% \begin{itemdecl} -template void lock(L1&, L2&, L3&...); +template void lock(L1&, L2&, L3&...); \end{itemdecl} \begin{itemdescr} @@ -2886,8 +2874,7 @@ Condition variable construction and destruction need not be synchronized. \rSec2[condition_variable.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{condition_variable}}% -\indexlibrary{\idxhdr{condition_variable}}% +\indexhdr{condition_variable}% \indexlibrary{\idxcode{cv_status}}% \begin{codeblock} @@ -2967,19 +2954,19 @@ void notify_one() noexcept; void notify_all() noexcept; void wait(unique_lock& lock); - template + template void wait(unique_lock& lock, Predicate pred); - template + template cv_status wait_until(unique_lock& lock, const chrono::time_point& abs_time); - template + template bool wait_until(unique_lock& lock, const chrono::time_point& abs_time, Predicate pred); - template + template cv_status wait_for(unique_lock& lock, const chrono::duration& rel_time); - template + template bool wait_for(unique_lock& lock, const chrono::duration& rel_time, Predicate pred); @@ -3091,7 +3078,7 @@ \indexlibrarymember{wait}{condition_variable}% \begin{itemdecl} -template +template void wait(unique_lock& lock, Predicate pred); \end{itemdecl} @@ -3131,7 +3118,7 @@ \indexlibrarymember{wait_until}{condition_variable}% \begin{itemdecl} -template +template cv_status wait_until(unique_lock& lock, const chrono::time_point& abs_time); \end{itemdecl} @@ -3187,7 +3174,7 @@ \indexlibrarymember{wait_for}{condition_variable}% \begin{itemdecl} -template +template cv_status wait_for(unique_lock& lock, const chrono::duration& rel_time); \end{itemdecl} @@ -3232,7 +3219,7 @@ \indexlibrarymember{wait_until}{condition_variable}% \begin{itemdecl} -template +template bool wait_until(unique_lock& lock, const chrono::time_point& abs_time, Predicate pred); @@ -3281,7 +3268,7 @@ \indexlibrarymember{wait_for}{condition_variable}% \begin{itemdecl} -template +template bool wait_for(unique_lock& lock, const chrono::duration& rel_time, Predicate pred); @@ -3355,19 +3342,19 @@ void notify_one() noexcept; void notify_all() noexcept; - template + template void wait(Lock& lock); - template + template void wait(Lock& lock, Predicate pred); - template + template cv_status wait_until(Lock& lock, const chrono::time_point& abs_time); - template + template bool wait_until(Lock& lock, const chrono::time_point& abs_time, Predicate pred); - template + template cv_status wait_for(Lock& lock, const chrono::duration& rel_time); - template + template bool wait_for(Lock& lock, const chrono::duration& rel_time, Predicate pred); }; } @@ -3437,7 +3424,7 @@ \indexlibrarymember{wait}{condition_variable_any}% \begin{itemdecl} -template +template void wait(Lock& lock); \end{itemdecl} @@ -3465,7 +3452,7 @@ \indexlibrarymember{wait}{condition_variable_any}% \begin{itemdecl} -template +template void wait(Lock& lock, Predicate pred); \end{itemdecl} @@ -3480,7 +3467,7 @@ \indexlibrarymember{wait_until}{condition_variable_any}% \begin{itemdecl} -template +template cv_status wait_until(Lock& lock, const chrono::time_point& abs_time); \end{itemdecl} @@ -3525,7 +3512,7 @@ \indexlibrarymember{wait_for}{condition_variable_any}% \begin{itemdecl} -template +template cv_status wait_for(Lock& lock, const chrono::duration& rel_time); \end{itemdecl} @@ -3558,7 +3545,7 @@ \indexlibrarymember{wait_until}{condition_variable_any}% \begin{itemdecl} -template +template bool wait_until(Lock& lock, const chrono::time_point& abs_time, Predicate pred); \end{itemdecl} @@ -3583,7 +3570,7 @@ \indexlibrarymember{wait_for}{condition_variable_any}% \begin{itemdecl} -template +template bool wait_for(Lock& lock, const chrono::duration& rel_time, Predicate pred); \end{itemdecl} @@ -3600,15 +3587,14 @@ \rSec2[futures.overview]{Overview} \pnum -\ref{futures} describes components that a \Cpp program can use to retrieve in one thread the +\ref{futures} describes components that a \Cpp{} program can use to retrieve in one thread the result (value or exception) from a function that has run in the same thread or another thread. \begin{note} These components are not restricted to multi-threaded programs but can be useful in single-threaded programs as well. \end{note} \rSec2[future.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{future}}% -\indexlibrary{\idxhdr{future}}% +\indexhdr{future}% \indexlibrary{\idxcode{future_errc}}% \begin{codeblock} namespace std { @@ -3631,7 +3617,7 @@ deferred }; - template <> struct is_error_code_enum : public true_type { }; + template<> struct is_error_code_enum : public true_type { }; error_code make_error_code(future_errc e) noexcept; error_condition make_error_condition(future_errc e) noexcept; @@ -3639,40 +3625,37 @@ class future_error; - template class promise; - template class promise; - template <> class promise; + template class promise; + template class promise; + template<> class promise; - template + template void swap(promise& x, promise& y) noexcept; - template + template struct uses_allocator, Alloc>; - template class future; - template class future; - template <> class future; + template class future; + template class future; + template<> class future; - template class shared_future; - template class shared_future; - template <> class shared_future; + template class shared_future; + template class shared_future; + template<> class shared_future; - template class packaged_task; // not defined - template + template class packaged_task; // not defined + template class packaged_task; - template + template void swap(packaged_task&, packaged_task&) noexcept; - template - struct uses_allocator, Alloc>; - - template - future, decay_t...>> - async(F&& f, Args&&... args); - template - future, decay_t...>> - async(launch policy, F&& f, Args&&... args); + template + [[nodiscard]] future, decay_t...>> + async(F&& f, Args&&... args); + template + [[nodiscard]] future, decay_t...>> + async(launch policy, F&& f, Args&&... args); } \end{codeblock} @@ -3771,7 +3754,7 @@ \begin{itemdescr} \pnum -\returns An \ntbs incorporating \tcode{code().message()}. +\returns An \ntbs{} incorporating \tcode{code().message()}. \end{itemdescr} \rSec2[futures.state]{Shared state} @@ -3891,11 +3874,11 @@ \indexlibrary{\idxcode{promise}}% \begin{codeblock} namespace std { - template + template class promise { public: promise(); - template + template promise(allocator_arg_t, const Allocator& a); promise(promise&& rhs) noexcept; promise(const promise& rhs) = delete; @@ -3918,10 +3901,10 @@ void set_exception_at_thread_exit(exception_ptr p); }; - template + template void swap(promise& x, promise& y) noexcept; - template + template struct uses_allocator, Alloc>; } \end{codeblock} @@ -3940,7 +3923,7 @@ \indexlibrary{\idxcode{uses_allocator}!\idxcode{promise}}% \begin{itemdecl} -template +template struct uses_allocator, Alloc> : true_type { }; \end{itemdecl} @@ -3954,7 +3937,7 @@ \indexlibrary{\idxcode{promise}!constructor}% \begin{itemdecl} promise(); -template +template promise(allocator_arg_t, const Allocator& a); \end{itemdecl} @@ -4168,7 +4151,7 @@ \indexlibrarymember{swap}{promise}% \begin{itemdecl} -template +template void swap(promise& x, promise& y) noexcept; \end{itemdecl} @@ -4211,7 +4194,7 @@ \indexlibrary{\idxcode{future}}% \begin{codeblock} namespace std { - template + template class future { public: future() noexcept; @@ -4229,9 +4212,9 @@ bool valid() const noexcept; void wait() const; - template + template future_status wait_for(const chrono::duration& rel_time) const; - template + template future_status wait_until(const chrono::time_point& abs_time) const; }; } @@ -4399,7 +4382,7 @@ \indexlibrarymember{wait_for}{future}% \begin{itemdecl} -template +template future_status wait_for(const chrono::duration& rel_time) const; \end{itemdecl} @@ -4432,7 +4415,7 @@ \indexlibrarymember{wait_until}{future}% \begin{itemdecl} -template +template future_status wait_until(const chrono::time_point& abs_time) const; \end{itemdecl} @@ -4496,7 +4479,7 @@ \indexlibrary{\idxcode{shared_future}}% \begin{codeblock} namespace std { - template + template class shared_future { public: shared_future() noexcept; @@ -4514,9 +4497,9 @@ bool valid() const noexcept; void wait() const; - template + template future_status wait_for(const chrono::duration& rel_time) const; - template + template future_status wait_until(const chrono::time_point& abs_time) const; }; } @@ -4712,7 +4695,7 @@ \indexlibrarymember{wait_for}{shared_future}% \begin{itemdecl} -template +template future_status wait_for(const chrono::duration& rel_time) const; \end{itemdecl} @@ -4746,7 +4729,7 @@ \indexlibrarymember{wait_until}{shared_future}% \begin{itemdecl} -template +template future_status wait_until(const chrono::time_point& abs_time) const; \end{itemdecl} @@ -4787,17 +4770,17 @@ \indexlibrary{\idxcode{async}}% \begin{itemdecl} -template - future, decay_t...>> +template + [[nodiscard]] future, decay_t...>> async(F&& f, Args&&... args); -template - future, decay_t...>> +template + [[nodiscard]] future, decay_t...>> async(launch policy, F&& f, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{F} and each \tcode{Ti} in \tcode{Args} shall +\requires \tcode{F} and each $\tcode{T}_i$ in \tcode{Args} shall satisfy the \tcode{MoveConstructible} requirements, and \begin{codeblock} @@ -4974,7 +4957,7 @@ public: // construction and destruction packaged_task() noexcept; - template + template explicit packaged_task(F&& f); ~packaged_task(); @@ -4999,11 +4982,8 @@ void reset(); }; - template + template void swap(packaged_task& x, packaged_task& y) noexcept; - - template - struct uses_allocator, Alloc>; } \end{codeblock} @@ -5021,7 +5001,7 @@ \indexlibrary{\idxcode{packaged_task}!constructor}% \begin{itemdecl} -template +template packaged_task(F&& f); \end{itemdecl} @@ -5043,14 +5023,9 @@ \pnum \throws -\begin{itemize} -\item Any exceptions thrown by the copy or move constructor of \tcode{f}. -\item For the first version, - \tcode{bad_alloc} if memory for the internal data structures could not be allocated. -\item For the second version, - any exceptions thrown by \tcode{allocator_traits::template} - \tcode{rebind_traits<\unspec>::allocate}. -\end{itemize} +Any exceptions thrown by the copy or move constructor of \tcode{f}, or +\tcode{bad_alloc} if memory for the internal data structures +could not be allocated. \end{itemdescr} \indexlibrary{\idxcode{packaged_task}!constructor}% @@ -5229,7 +5204,7 @@ \indexlibrarymember{swap}{packaged_task}% \begin{itemdecl} -template +template void swap(packaged_task& x, packaged_task& y) noexcept; \end{itemdecl} @@ -5237,15 +5212,3 @@ \pnum \effects As if by \tcode{x.swap(y)}. \end{itemdescr} - -\indexlibrary{\idxcode{uses_allocator}!\idxcode{packaged_task}}% -\begin{itemdecl} -template - struct uses_allocator, Alloc> - : true_type { }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{Alloc} shall be an Allocator\iref{allocator.requirements}. -\end{itemdescr} diff --git a/source/utilities.tex b/source/utilities.tex index d6107533ef..59a09a3d45 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -4,8 +4,8 @@ \rSec1[utilities.general]{General} \pnum -This Clause describes utilities that are generally useful in \Cpp programs; some -of these utilities are used by other elements of the \Cpp standard library. +This Clause describes utilities that are generally useful in \Cpp{} programs; some +of these utilities are used by other elements of the \Cpp{} standard library. These utilities are summarized in Table~\ref{tab:util.lib.summary}. \begin{libsumtab}{General utilities library summary}{tab:util.lib.summary} @@ -28,7 +28,8 @@ \ref{time} & Time utilities & \tcode{} \\ & & \tcode{} \\ \rowsep \ref{type.index} & Type indexes & \tcode{} \\ \rowsep -\ref{execpol} & Execution policies & \tcode{} \\ +\ref{execpol} & Execution policies & \tcode{} \\ \rowsep +\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \end{libsumtab} \rSec1[utility]{Utility components} @@ -37,8 +38,7 @@ This subclause contains some basic function and class templates that are used throughout the rest of the library. -\indextext{\idxhdr{utility}}% -\indexlibrary{\idxhdr{utility}}% +\indexhdr{utility}% \indexlibrary{\idxcode{rel_ops}}% \rSec2[utility.syn]{Header \tcode{} synopsis} @@ -46,44 +46,36 @@ #include // see \ref{initializer_list.syn} namespace std { - // \ref{operators}, operators - namespace rel_ops { - template bool operator!=(const T&, const T&); - template bool operator> (const T&, const T&); - template bool operator<=(const T&, const T&); - template bool operator>=(const T&, const T&); - } - // \ref{utility.swap}, swap - template + template void swap(T& a, T& b) noexcept(@\seebelow@); - template + template void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); // \ref{utility.exchange}, exchange - template - T exchange(T& obj, U&& new_val); + template + constexpr T exchange(T& obj, U&& new_val); // \ref{forward}, forward/move - template + template constexpr T&& forward(remove_reference_t& t) noexcept; - template + template constexpr T&& forward(remove_reference_t&& t) noexcept; - template + template constexpr remove_reference_t&& move(T&&) noexcept; - template + template constexpr conditional_t< !is_nothrow_move_constructible_v && is_copy_constructible_v, const T&, T&&> move_if_noexcept(T& x) noexcept; // \ref{utility.as_const}, \tcode{as_const} - template + template constexpr add_const_t& as_const(T& t) noexcept; - template + template void as_const(const T&&) = delete; // \ref{declval}, declval - template + template add_rvalue_reference_t declval() noexcept; // as unevaluated operand @% \indexlibrary{\idxcode{index_sequence}}% @@ -105,35 +97,35 @@ using index_sequence_for = make_index_sequence; // \ref{pairs}, class template \tcode{pair} - template + template struct pair; // \ref{pairs.spec}, pair specialized algorithms - template + template constexpr bool operator==(const pair&, const pair&); - template + template constexpr bool operator< (const pair&, const pair&); - template + template constexpr bool operator!=(const pair&, const pair&); - template + template constexpr bool operator> (const pair&, const pair&); - template + template constexpr bool operator>=(const pair&, const pair&); - template + template constexpr bool operator<=(const pair&, const pair&); - template + template void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); - template + template constexpr @\seebelow@ make_pair(T1&&, T2&&); // \ref{pair.astuple}, tuple-like access to pair - template class tuple_size; - template class tuple_element; + template class tuple_size; + template class tuple_element; - template struct tuple_size>; - template struct tuple_element>; + template struct tuple_size>; + template struct tuple_element>; template constexpr tuple_element_t>& get(pair&) noexcept; @@ -143,21 +135,21 @@ constexpr const tuple_element_t>& get(const pair&) noexcept; template constexpr const tuple_element_t>&& get(const pair&&) noexcept; - template + template constexpr T1& get(pair& p) noexcept; - template + template constexpr const T1& get(const pair& p) noexcept; - template + template constexpr T1&& get(pair&& p) noexcept; - template + template constexpr const T1&& get(const pair&& p) noexcept; - template + template constexpr T2& get(pair& p) noexcept; - template + template constexpr const T2& get(const pair& p) noexcept; - template + template constexpr T2&& get(pair&& p) noexcept; - template + template constexpr const T2&& get(const pair&& p) noexcept; // \ref{pair.piecewise}, pair piecewise construction @@ -165,23 +157,23 @@ explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{}; - template class tuple; // defined in \tcode{}\iref{tuple.syn} + template class tuple; // defined in \tcode{}\iref{tuple.syn} // in-place construction struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; - template + template struct in_place_type_t { explicit in_place_type_t() = default; }; - template inline constexpr in_place_type_t in_place_type{}; - template + template inline constexpr in_place_type_t in_place_type{}; + template struct in_place_index_t { explicit in_place_index_t() = default; }; - template inline constexpr in_place_index_t in_place_index{}; + template inline constexpr in_place_index_t in_place_index{}; } \end{codeblock} @@ -198,84 +190,11 @@ \tcode{fixed}, and \tcode{hex}. -\rSec2[operators]{Operators} - -\pnum -To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} -and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, -the library provides the following: - -\indexlibrary{\idxcode{operator"!=}}% -\begin{itemdecl} -template bool operator!=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Type \tcode{T} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). - -\pnum -\returns -\tcode{!(x == y)}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator>}}% -\begin{itemdecl} -template bool operator>(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). - -\pnum -\returns -\tcode{y < x}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator<=}}% -\begin{itemdecl} -template bool operator<=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). - -\pnum -\returns -\tcode{!(y < x)}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator>=}}% -\begin{itemdecl} -template bool operator>=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Type \tcode{T} is \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). - -\pnum -\returns -\tcode{!(x < y)}. -\end{itemdescr} - -\pnum -In this library, whenever a declaration is provided for an \tcode{operator!=}, -\tcode{operator>}, \tcode{operator>=}, or \tcode{operator<=}, -and requirements and semantics are not explicitly provided, -the requirements and semantics are as specified in this Clause. - \rSec2[utility.swap]{\tcode{swap}} \indexlibrary{\idxcode{swap}}% \begin{itemdecl} -template +template void swap(T& a, T& b) noexcept(@\seebelow@); \end{itemdecl} @@ -306,7 +225,7 @@ \indexlibrary{\idxcode{swap}}% \begin{itemdecl} -template +template void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); \end{itemdecl} @@ -329,7 +248,8 @@ \indexlibrary{\idxcode{exchange}}% \begin{itemdecl} -template T exchange(T& obj, U&& new_val); +template + constexpr T exchange(T& obj, U&& new_val); \end{itemdecl} \begin{itemdescr} @@ -358,8 +278,8 @@ \indexlibrary{\idxcode{forward}}% \indextext{\idxcode{forward}}% \begin{itemdecl} -template constexpr T&& forward(remove_reference_t& t) noexcept; -template constexpr T&& forward(remove_reference_t&& t) noexcept; +template constexpr T&& forward(remove_reference_t& t) noexcept; +template constexpr T&& forward(remove_reference_t&& t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -372,7 +292,7 @@ \pnum \begin{example} \begin{codeblock} -template +template shared_ptr factory(A1&& a1, A2&& a2) { return shared_ptr(new T(std::forward(a1), std::forward(a2))); } @@ -401,7 +321,7 @@ \indexlibrary{\idxcode{move}!function}% \indextext{\idxcode{move}}% \begin{itemdecl} -template constexpr remove_reference_t&& move(T&& t) noexcept; +template constexpr remove_reference_t&& move(T&& t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -412,7 +332,7 @@ \pnum \begin{example} \begin{codeblock} -template +template shared_ptr factory(A1&& a1) { return shared_ptr(new T(std::forward(a1))); } @@ -443,7 +363,7 @@ \indexlibrary{\idxcode{move_if_noexcept}}% \begin{itemdecl} -template constexpr conditional_t< +template constexpr conditional_t< !is_nothrow_move_constructible_v && is_copy_constructible_v, const T&, T&&> move_if_noexcept(T& x) noexcept; \end{itemdecl} @@ -457,7 +377,7 @@ \indexlibrary{\idxcode{as_const}}% \begin{itemdecl} -template constexpr add_const_t& as_const(T& t) noexcept; +template constexpr add_const_t& as_const(T& t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -469,11 +389,11 @@ \pnum The library provides the function template \tcode{declval} to simplify the definition of -expressions which occur as unevaluated operands\iref{expr}. +expressions which occur as unevaluated operands\iref{expr.prop}. \indexlibrary{\idxcode{declval}}% \begin{itemdecl} -template add_rvalue_reference_t declval() noexcept; // as unevaluated operand +template add_rvalue_reference_t declval() noexcept; // as unevaluated operand \end{itemdecl} \begin{itemdescr} @@ -487,7 +407,7 @@ \pnum \begin{example} \begin{codeblock} -template decltype(static_cast(declval())) convert(From&&); +template decltype(static_cast(declval())) convert(From&&); \end{codeblock} declares a function template \tcode{convert} which only participates in overloading if the type \tcode{From} can be explicitly converted to type \tcode{To}. For another example see class @@ -510,6 +430,7 @@ \rSec2[intseq.intseq]{Class template \tcode{integer_sequence}} \indexlibrary{\idxcode{integer_sequence}}% +\indexlibrarymember{value_type}{integer_sequence}% \begin{codeblock} namespace std { template @@ -561,7 +482,7 @@ \indexlibrary{\idxcode{pair}}% \begin{codeblock} namespace std { - template + template struct pair { using first_type = T1; using second_type = T2; @@ -576,7 +497,7 @@ template @\EXPLICIT@ constexpr pair(U1&& x, U2&& y); template @\EXPLICIT@ constexpr pair(const pair& p); template @\EXPLICIT@ constexpr pair(pair&& p); - template + template pair(piecewise_construct_t, tuple first_args, tuple second_args); pair& operator=(const pair& p); @@ -782,7 +703,7 @@ and to \tcode{second} with\\ \tcode{std::forward(p.second)}. \pnum -\remarks This operator shall be defined as deleted unless +\remarks This operator shall not participate in overload resolution unless \tcode{is_move_assignable_v} is \tcode{true} and \tcode{is_move_assignable_v} is \tcode{true}. @@ -843,7 +764,7 @@ \indexlibrarymember{operator==}{pair}% \begin{itemdecl} -template +template constexpr bool operator==(const pair& x, const pair& y); \end{itemdecl} @@ -855,7 +776,7 @@ \indexlibrarymember{operator<}{pair}% \begin{itemdecl} -template +template constexpr bool operator<(const pair& x, const pair& y); \end{itemdecl} @@ -867,7 +788,7 @@ \indexlibrarymember{operator"!=}{pair}% \begin{itemdecl} -template +template constexpr bool operator!=(const pair& x, const pair& y); \end{itemdecl} @@ -878,7 +799,7 @@ \indexlibrarymember{operator>}{pair}% \begin{itemdecl} -template +template constexpr bool operator>(const pair& x, const pair& y); \end{itemdecl} @@ -889,7 +810,7 @@ \indexlibrarymember{operator>=}{pair}% \begin{itemdecl} -template +template constexpr bool operator>=(const pair& x, const pair& y); \end{itemdecl} @@ -900,7 +821,7 @@ \indexlibrarymember{operator<=}{pair}% \begin{itemdecl} -template +template constexpr bool operator<=(const pair& x, const pair& y); \end{itemdecl} @@ -929,7 +850,7 @@ \indexlibrary{\idxcode{make_pair}}% \begin{itemdecl} -template +template constexpr pair make_pair(T1&& x, T2&& y); \end{itemdecl} @@ -948,7 +869,7 @@ \begin{codeblock} return pair(5, 3.1415926); // explicit types \end{codeblock} -a \Cpp program may contain: +a \Cpp{} program may contain: \begin{codeblock} return make_pair(5, 3.1415926); // types are deduced \end{codeblock} @@ -958,7 +879,7 @@ \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} -template +template struct tuple_size> : integral_constant { }; \end{itemdecl} @@ -995,13 +916,13 @@ \indexlibrarymember{get}{pair}% \begin{itemdecl} -template +template constexpr T1& get(pair& p) noexcept; -template +template constexpr const T1& get(const pair& p) noexcept; -template +template constexpr T1&& get(pair&& p) noexcept; -template +template constexpr const T1&& get(const pair&& p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1014,13 +935,13 @@ \indexlibrarymember{get}{pair}% \begin{itemdecl} -template +template constexpr T2& get(pair& p) noexcept; -template +template constexpr const T2& get(const pair& p) noexcept; -template +template constexpr T2&& get(pair&& p) noexcept; -template +template constexpr const T2&& get(const pair&& p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1066,71 +987,70 @@ \rSec2[tuple.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{tuple}}% -\indexlibrary{\idxhdr{tuple}}% +\indexhdr{tuple}% \begin{codeblock} namespace std { // \ref{tuple.tuple}, class template \tcode{tuple} - template + template class tuple; // \ref{tuple.creation}, tuple creation functions inline constexpr @\unspec@ ignore; - template + template constexpr tuple make_tuple(TTypes&&...); - template + template constexpr tuple forward_as_tuple(TTypes&&...) noexcept; template constexpr tuple tie(TTypes&...) noexcept; - template + template constexpr tuple tuple_cat(Tuples&&...); // \ref{tuple.apply}, calling a function with a tuple of arguments - template + template constexpr decltype(auto) apply(F&& f, Tuple&& t); - template + template constexpr T make_from_tuple(Tuple&& t); // \ref{tuple.helper}, tuple helper classes - template class tuple_size; // not defined - template class tuple_size; - template class tuple_size; - template class tuple_size; + template class tuple_size; // not defined + template class tuple_size; + template class tuple_size; + template class tuple_size; - template class tuple_size>; + template class tuple_size>; - template class tuple_element; // not defined - template class tuple_element; - template class tuple_element; - template class tuple_element; + template class tuple_element; // not defined + template class tuple_element; + template class tuple_element; + template class tuple_element; - template + template class tuple_element>; - template + template using tuple_element_t = typename tuple_element::type; // \ref{tuple.elem}, element access - template + template constexpr tuple_element_t>& get(tuple&) noexcept; - template + template constexpr tuple_element_t>&& get(tuple&&) noexcept; - template + template constexpr const tuple_element_t>& get(const tuple&) noexcept; - template + template constexpr const tuple_element_t>&& get(const tuple&&) noexcept; - template + template constexpr T& get(tuple& t) noexcept; - template + template constexpr T&& get(tuple&& t) noexcept; - template + template constexpr const T& get(const tuple& t) noexcept; - template + template constexpr const T&& get(const tuple&& t) noexcept; // \ref{tuple.rel}, relational operators @@ -1148,15 +1068,15 @@ constexpr bool operator>=(const tuple&, const tuple&); // \ref{tuple.traits}, allocator-related traits - template + template struct uses_allocator, Alloc>; // \ref{tuple.special}, specialized algorithms - template + template void swap(tuple& x, tuple& y) noexcept(@\seebelow@); // \ref{tuple.helper}, tuple helper classes - template + template inline constexpr size_t tuple_size_v = tuple_size::value; } \end{codeblock} @@ -1166,60 +1086,60 @@ \begin{codeblock} namespace std { - template - class tuple { + template + class tuple { public: // \ref{tuple.cnstr}, \tcode{tuple} construction @\EXPLICIT@ constexpr tuple(); @\EXPLICIT@ constexpr tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} - template + template @\EXPLICIT@ constexpr tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} tuple(const tuple&) = default; tuple(tuple&&) = default; - template + template @\EXPLICIT@ constexpr tuple(const tuple&); - template + template @\EXPLICIT@ constexpr tuple(tuple&&); - template + template @\EXPLICIT@ constexpr tuple(const pair&); // only if \tcode{sizeof...(Types) == 2} - template + template @\EXPLICIT@ constexpr tuple(pair&&); // only if \tcode{sizeof...(Types) == 2} // allocator-extended constructors - template + template tuple(allocator_arg_t, const Alloc& a); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const Types&...); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, UTypes&&...); - template + template tuple(allocator_arg_t, const Alloc& a, const tuple&); - template + template tuple(allocator_arg_t, const Alloc& a, tuple&&); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const tuple&); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, tuple&&); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const pair&); - template + template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, pair&&); // \ref{tuple.assign}, \tcode{tuple} assignment tuple& operator=(const tuple&); tuple& operator=(tuple&&) noexcept(@\seebelow@); - template + template tuple& operator=(const tuple&); - template + template tuple& operator=(tuple&&); - template + template tuple& operator=(const pair&); // only if \tcode{sizeof...(Types) == 2} - template + template tuple& operator=(pair&&); // only if \tcode{sizeof...(Types) == 2} // \ref{tuple.swap}, \tcode{tuple} swap @@ -1254,7 +1174,7 @@ constexpr functions. \pnum -The destructor of tuple shall be a trivial destructor if +The destructor of \tcode{tuple} shall be a trivial destructor if \tcode{(is_trivially_destructible_v \&\& ...)} is \tcode{true}. @@ -1306,7 +1226,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(UTypes&&... u); +template @\EXPLICIT@ constexpr tuple(UTypes&&... u); \end{itemdecl} \begin{itemdescr} @@ -1353,7 +1273,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(const tuple& u); +template @\EXPLICIT@ constexpr tuple(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1381,7 +1301,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(tuple&& u); +template @\EXPLICIT@ constexpr tuple(tuple&& u); \end{itemdecl} \begin{itemdescr} @@ -1413,7 +1333,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(const pair& u); +template @\EXPLICIT@ constexpr tuple(const pair& u); \end{itemdecl} \begin{itemdescr} @@ -1436,7 +1356,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(pair&& u); +template @\EXPLICIT@ constexpr tuple(pair&& u); \end{itemdecl} \begin{itemdescr} @@ -1459,23 +1379,23 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template +template tuple(allocator_arg_t, const Alloc& a); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const Types&...); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, UTypes&&...); -template +template tuple(allocator_arg_t, const Alloc& a, const tuple&); -template +template tuple(allocator_arg_t, const Alloc& a, tuple&&); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const tuple&); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, tuple&&); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const pair&); -template +template @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, pair&&); \end{itemdecl} @@ -1528,7 +1448,7 @@ \tcode{get<$i$>(*this)}. \pnum -\remarks This operator shall be defined as deleted unless +\remarks This operator shall not participate in overload resolution unless \tcode{is_move_assignable_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. \pnum @@ -1546,7 +1466,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -template tuple& operator=(const tuple& u); +template tuple& operator=(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1565,7 +1485,7 @@ \indexlibrarymember{operator=}{tuple}% \begin{itemdecl} -template tuple& operator=(tuple&& u); +template tuple& operator=(tuple&& u); \end{itemdecl} \begin{itemdescr} @@ -1585,7 +1505,7 @@ \indexlibrarymember{operator=}{tuple}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template tuple& operator=(const pair& u); +template tuple& operator=(const pair& u); \end{itemdecl} \begin{itemdescr} @@ -1607,7 +1527,7 @@ \indexlibrarymember{operator=}{tuple}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template tuple& operator=(pair&& u); +template tuple& operator=(pair&& u); \end{itemdecl} \begin{itemdescr} @@ -1740,7 +1660,7 @@ \indexlibrary{\idxcode{tuple_cat}} \begin{itemdecl} -template +template constexpr tuple tuple_cat(Tuples&&... tpls); \end{itemdecl} @@ -1792,7 +1712,7 @@ \indexlibrary{\idxcode{apply}}% \begin{itemdecl} -template +template constexpr decltype(auto) apply(F&& f, Tuple&& t); \end{itemdecl} @@ -1801,7 +1721,7 @@ \effects Given the exposition-only function: \begin{codeblock} -template +template constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence) { // exposition only return @\placeholdernc{INVOKE}@(std::forward(f), std::get(std::forward(t))...); // see \ref{func.require} @@ -1810,13 +1730,13 @@ Equivalent to: \begin{codeblock} return apply_impl(std::forward(f), std::forward(t), - make_index_sequence>>{}); + make_index_sequence>>{}); \end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{make_from_tuple}}% \begin{itemdecl} -template +template constexpr T make_from_tuple(Tuple&& t); \end{itemdecl} @@ -1825,15 +1745,16 @@ \effects Given the exposition-only function: \begin{codeblock} -template +template constexpr T make_from_tuple_impl(Tuple&& t, index_sequence) { // exposition only return T(get(std::forward(t))...); } \end{codeblock} Equivalent to: \begin{codeblock} -return make_from_tuple_impl(forward(t), - make_index_sequence>>{}); +return make_from_tuple_impl( + forward(t), + make_index_sequence>>{}); \end{codeblock} \begin{note} The type of \tcode{T} must be supplied as an explicit template parameter, @@ -1844,7 +1765,7 @@ \indexlibrary{\idxcode{tuple_size}!in general}% \begin{itemdecl} -template struct tuple_size; +template struct tuple_size; \end{itemdecl} \begin{itemdescr} @@ -1857,13 +1778,13 @@ \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} -template +template class tuple_size> : public integral_constant { }; \end{itemdecl} \indexlibrary{\idxcode{tuple_element}}% \begin{itemdecl} -template +template class tuple_element> { public: using type = TI; @@ -1883,9 +1804,9 @@ \indexlibrary{\idxcode{tuple_size}}% \begin{itemdecl} -template class tuple_size; -template class tuple_size; -template class tuple_size; +template class tuple_size; +template class tuple_size; +template class tuple_size; \end{itemdecl} \begin{itemdescr} @@ -1920,9 +1841,9 @@ \indexlibrary{\idxcode{tuple_element}}% \begin{itemdecl} -template class tuple_element; -template class tuple_element; -template class tuple_element; +template class tuple_element; +template class tuple_element; +template class tuple_element; \end{itemdecl} \begin{itemdescr} @@ -1951,16 +1872,16 @@ \indexlibrarymember{get}{tuple}% \begin{itemdecl} -template +template constexpr tuple_element_t>& get(tuple& t) noexcept; -template +template constexpr tuple_element_t>&& get(tuple&& t) noexcept; // Note A -template +template constexpr const tuple_element_t>& get(const tuple& t) noexcept; // Note B -template +template constexpr const tuple_element_t>&& get(const tuple&& t) noexcept; \end{itemdecl} @@ -1995,13 +1916,13 @@ \indexlibrarymember{get}{tuple}% \begin{itemdecl} -template +template constexpr T& get(tuple& t) noexcept; -template +template constexpr T&& get(tuple&& t) noexcept; -template +template constexpr const T& get(const tuple& t) noexcept; -template +template constexpr const T&& get(const tuple&& t) noexcept; \end{itemdecl} @@ -2137,7 +2058,7 @@ \indexlibrary{\idxcode{uses_allocator}}% \begin{itemdecl} -template +template struct uses_allocator, Alloc> : true_type { }; \end{itemdecl} @@ -2155,7 +2076,7 @@ \indexlibrary{\idxcode{swap}}% \begin{itemdecl} -template +template void swap(tuple& x, tuple& y) noexcept(@\seebelow@); \end{itemdecl} @@ -2190,12 +2111,11 @@ \rSec2[optional.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{optional}}% -\indexlibrary{\idxhdr{optional}}% +\indexhdr{optional}% \begin{codeblock} namespace std { // \ref{optional.optional}, class template \tcode{optional} - template + template class optional; // \ref{optional.nullopt}, no-value state indicator @@ -2206,61 +2126,61 @@ class bad_optional_access; // \ref{optional.relops}, relational operators - template + template constexpr bool operator==(const optional&, const optional&); - template + template constexpr bool operator!=(const optional&, const optional&); - template + template constexpr bool operator<(const optional&, const optional&); - template + template constexpr bool operator>(const optional&, const optional&); - template + template constexpr bool operator<=(const optional&, const optional&); - template + template constexpr bool operator>=(const optional&, const optional&); // \ref{optional.nullops}, comparison with \tcode{nullopt} - template constexpr bool operator==(const optional&, nullopt_t) noexcept; - template constexpr bool operator==(nullopt_t, const optional&) noexcept; - template constexpr bool operator!=(const optional&, nullopt_t) noexcept; - template constexpr bool operator!=(nullopt_t, const optional&) noexcept; - template constexpr bool operator<(const optional&, nullopt_t) noexcept; - template constexpr bool operator<(nullopt_t, const optional&) noexcept; - template constexpr bool operator<=(const optional&, nullopt_t) noexcept; - template constexpr bool operator<=(nullopt_t, const optional&) noexcept; - template constexpr bool operator>(const optional&, nullopt_t) noexcept; - template constexpr bool operator>(nullopt_t, const optional&) noexcept; - template constexpr bool operator>=(const optional&, nullopt_t) noexcept; - template constexpr bool operator>=(nullopt_t, const optional&) noexcept; + template constexpr bool operator==(const optional&, nullopt_t) noexcept; + template constexpr bool operator==(nullopt_t, const optional&) noexcept; + template constexpr bool operator!=(const optional&, nullopt_t) noexcept; + template constexpr bool operator!=(nullopt_t, const optional&) noexcept; + template constexpr bool operator<(const optional&, nullopt_t) noexcept; + template constexpr bool operator<(nullopt_t, const optional&) noexcept; + template constexpr bool operator<=(const optional&, nullopt_t) noexcept; + template constexpr bool operator<=(nullopt_t, const optional&) noexcept; + template constexpr bool operator>(const optional&, nullopt_t) noexcept; + template constexpr bool operator>(nullopt_t, const optional&) noexcept; + template constexpr bool operator>=(const optional&, nullopt_t) noexcept; + template constexpr bool operator>=(nullopt_t, const optional&) noexcept; // \ref{optional.comp_with_t}, comparison with \tcode{T} - template constexpr bool operator==(const optional&, const U&); - template constexpr bool operator==(const U&, const optional&); - template constexpr bool operator!=(const optional&, const U&); - template constexpr bool operator!=(const U&, const optional&); - template constexpr bool operator<(const optional&, const U&); - template constexpr bool operator<(const U&, const optional&); - template constexpr bool operator<=(const optional&, const U&); - template constexpr bool operator<=(const U&, const optional&); - template constexpr bool operator>(const optional&, const U&); - template constexpr bool operator>(const U&, const optional&); - template constexpr bool operator>=(const optional&, const U&); - template constexpr bool operator>=(const U&, const optional&); + template constexpr bool operator==(const optional&, const U&); + template constexpr bool operator==(const T&, const optional&); + template constexpr bool operator!=(const optional&, const U&); + template constexpr bool operator!=(const T&, const optional&); + template constexpr bool operator<(const optional&, const U&); + template constexpr bool operator<(const T&, const optional&); + template constexpr bool operator<=(const optional&, const U&); + template constexpr bool operator<=(const T&, const optional&); + template constexpr bool operator>(const optional&, const U&); + template constexpr bool operator>(const T&, const optional&); + template constexpr bool operator>=(const optional&, const U&); + template constexpr bool operator>=(const T&, const optional&); // \ref{optional.specalg}, specialized algorithms - template + template void swap(optional&, optional&) noexcept(@\seebelow@); - template + template constexpr optional<@\seebelow@> make_optional(T&&); - template + template constexpr optional make_optional(Args&&... args); - template + template constexpr optional make_optional(initializer_list il, Args&&... args); // \ref{optional.hash}, hash support - template struct hash; - template struct hash>; + template struct hash; + template struct hash>; } \end{codeblock} @@ -2272,8 +2192,9 @@ \rSec2[optional.optional]{Class template \tcode{optional}} \indexlibrary{\idxcode{optional}}% +\indexlibrarymember{value_type}{optional}% \begin{codeblock} -template +template class optional { public: using value_type = T; @@ -2283,15 +2204,15 @@ constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(@\seebelow@); - template + template constexpr explicit optional(in_place_t, Args&&...); - template + template constexpr explicit optional(in_place_t, initializer_list, Args&&...); - template + template @\EXPLICIT@ constexpr optional(U&&); - template + template @\EXPLICIT@ optional(const optional&); - template + template @\EXPLICIT@ optional(optional&&); // \ref{optional.dtor}, destructor @@ -2301,11 +2222,11 @@ optional& operator=(nullopt_t) noexcept; optional& operator=(const optional&); optional& operator=(optional&&) noexcept(@\seebelow@); - template optional& operator=(U&&); - template optional& operator=(const optional&); - template optional& operator=(optional&&); - template T& emplace(Args&&...); - template T& emplace(initializer_list, Args&&...); + template optional& operator=(U&&); + template optional& operator=(const optional&); + template optional& operator=(optional&&); + template T& emplace(Args&&...); + template T& emplace(initializer_list, Args&&...); // \ref{optional.swap}, swap void swap(optional&) noexcept(@\seebelow@); @@ -2323,8 +2244,8 @@ constexpr T& value() &; constexpr T&& value() &&; constexpr const T&& value() const&&; - template constexpr T value_or(U&&) const&; - template constexpr T value_or(U&&) &&; + template constexpr T value_or(U&&) const&; + template constexpr T value_or(U&&) &&; // \ref{optional.mod}, modifiers void reset() noexcept; @@ -2431,7 +2352,7 @@ \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template constexpr explicit optional(in_place_t, Args&&... args); +template constexpr explicit optional(in_place_t, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -2456,7 +2377,7 @@ \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template +template constexpr explicit optional(in_place_t, initializer_list il, Args&&... args); \end{itemdecl} @@ -2488,7 +2409,7 @@ \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr optional(U&& v); +template @\EXPLICIT@ constexpr optional(U&& v); \end{itemdecl} \begin{itemdescr} @@ -2511,15 +2432,15 @@ this constructor shall be a constexpr constructor. This constructor shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true}, -\tcode{is_same_v, in_place_t>} is \tcode{false}, and -\tcode{is_same_v, decay_t>} is \tcode{false}. +\tcode{is_same_v, in_place_t>} is \tcode{false}, and +\tcode{is_same_v, optional>} is \tcode{false}. The constructor is explicit if and only if \tcode{is_convertible_v} is \tcode{false}. \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ optional(const optional& rhs); +template @\EXPLICIT@ optional(const optional& rhs); \end{itemdecl} \begin{itemdescr} @@ -2557,7 +2478,7 @@ \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ optional(optional&& rhs); +template @\EXPLICIT@ optional(optional&& rhs); \end{itemdecl} \begin{itemdescr} @@ -2729,7 +2650,7 @@ \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -template optional& operator=(U&& v); +template optional& operator=(U&& v); \end{itemdecl} \begin{itemdescr} @@ -2749,7 +2670,7 @@ \remarks If any exception is thrown, the result of the expression \tcode{bool(*this)} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, the state of \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, the state of \tcode{*val} and \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s assignment. This function shall not participate in overload resolution unless -\tcode{is_same_v, decay_t>} is \tcode{false}, +\tcode{is_same_v, optional>} is \tcode{false}, \tcode{conjunction_v, is_same>>} is \tcode{false}, \tcode{is_constructible_v} is \tcode{true}, and \tcode{is_assignable_v} is \tcode{true}. @@ -2757,7 +2678,7 @@ \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -template optional& operator=(const optional& rhs); +template optional& operator=(const optional& rhs); \end{itemdecl} \begin{itemdescr} @@ -2818,7 +2739,7 @@ \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -template optional& operator=(optional&& rhs); +template optional& operator=(optional&& rhs); \end{itemdecl} \begin{itemdescr} @@ -2880,7 +2801,7 @@ \indexlibrarymember{emplace}{optional}% \begin{itemdecl} -template T& emplace(Args&&... args); +template T& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -2911,7 +2832,7 @@ \indexlibrarymember{emplace}{optional}% \begin{itemdecl} -template T& emplace(initializer_list il, Args&&... args); +template T& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -3116,7 +3037,7 @@ \indexlibrarymember{value_or}{optional}% \begin{itemdecl} -template constexpr T value_or(U&& v) const&; +template constexpr T value_or(U&& v) const&; \end{itemdecl} \begin{itemdescr} @@ -3135,7 +3056,7 @@ \indexlibrarymember{value_or}{optional}% \begin{itemdecl} -template constexpr T value_or(U&& v) &&; +template constexpr T value_or(U&& v) &&; \end{itemdecl} \begin{itemdescr} @@ -3214,14 +3135,14 @@ \postconditions \tcode{what()} returns an \impldef{return value of \tcode{bad_optional_access::what}} -\ntbs. +\ntbs{}. \end{itemdescr} \rSec2[optional.relops]{Relational operators} \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const optional& x, const optional& y); +template constexpr bool operator==(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3244,7 +3165,7 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const optional& x, const optional& y); +template constexpr bool operator!=(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3268,7 +3189,7 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const optional& x, const optional& y); +template constexpr bool operator<(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3292,7 +3213,7 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const optional& x, const optional& y); +template constexpr bool operator>(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3316,7 +3237,7 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const optional& x, const optional& y); +template constexpr bool operator<=(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3340,7 +3261,7 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const optional& x, const optional& y); +template constexpr bool operator>=(const optional& x, const optional& y); \end{itemdecl} \begin{itemdescr} @@ -3366,8 +3287,8 @@ \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const optional& x, nullopt_t) noexcept; -template constexpr bool operator==(nullopt_t, const optional& x) noexcept; +template constexpr bool operator==(const optional& x, nullopt_t) noexcept; +template constexpr bool operator==(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3378,8 +3299,8 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const optional& x, nullopt_t) noexcept; -template constexpr bool operator!=(nullopt_t, const optional& x) noexcept; +template constexpr bool operator!=(const optional& x, nullopt_t) noexcept; +template constexpr bool operator!=(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3390,7 +3311,7 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const optional& x, nullopt_t) noexcept; +template constexpr bool operator<(const optional& x, nullopt_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3401,7 +3322,7 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(nullopt_t, const optional& x) noexcept; +template constexpr bool operator<(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3412,7 +3333,7 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const optional& x, nullopt_t) noexcept; +template constexpr bool operator<=(const optional& x, nullopt_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3423,7 +3344,7 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(nullopt_t, const optional& x) noexcept; +template constexpr bool operator<=(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3434,7 +3355,7 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const optional& x, nullopt_t) noexcept; +template constexpr bool operator>(const optional& x, nullopt_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3445,7 +3366,7 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(nullopt_t, const optional& x) noexcept; +template constexpr bool operator>(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3456,7 +3377,7 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const optional& x, nullopt_t) noexcept; +template constexpr bool operator>=(const optional& x, nullopt_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3467,7 +3388,7 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(nullopt_t, const optional& x) noexcept; +template constexpr bool operator>=(nullopt_t, const optional& x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3480,7 +3401,7 @@ \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const optional& x, const U& v); +template constexpr bool operator==(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3499,7 +3420,7 @@ \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const U& v, const optional& x); +template constexpr bool operator==(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3515,7 +3436,7 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const optional& x, const U& v); +template constexpr bool operator!=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3531,7 +3452,7 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const U& v, const optional& x); +template constexpr bool operator!=(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3547,7 +3468,7 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const optional& x, const U& v); +template constexpr bool operator<(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3563,7 +3484,7 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const U& v, const optional& x); +template constexpr bool operator<(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3579,7 +3500,7 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const optional& x, const U& v); +template constexpr bool operator<=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3595,7 +3516,7 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const U& v, const optional& x); +template constexpr bool operator<=(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3611,7 +3532,7 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const optional& x, const U& v); +template constexpr bool operator>(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3627,7 +3548,7 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const U& v, const optional& x); +template constexpr bool operator>(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3643,7 +3564,7 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const optional& x, const U& v); +template constexpr bool operator>=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} @@ -3659,7 +3580,7 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const U& v, const optional& x); +template constexpr bool operator>=(const T& v, const optional& x); \end{itemdecl} \begin{itemdescr} @@ -3678,7 +3599,7 @@ \indexlibrary{\idxcode{swap}!\idxcode{optional}}% \begin{itemdecl} -template void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))); +template void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -3694,7 +3615,7 @@ \indexlibrary{\idxcode{make_optional}}% \begin{itemdecl} -template constexpr optional> make_optional(T&& v); +template constexpr optional> make_optional(T&& v); \end{itemdecl} \begin{itemdescr} @@ -3705,7 +3626,7 @@ \indexlibrary{\idxcode{make_optional}}% \begin{itemdecl} -template +template constexpr optional make_optional(Args&&... args); \end{itemdecl} @@ -3716,7 +3637,7 @@ \indexlibrary{\idxcode{make_optional}}% \begin{itemdecl} -template +template constexpr optional make_optional(initializer_list il, Args&&... args); \end{itemdecl} @@ -3729,7 +3650,7 @@ \indexlibrary{\idxcode{hash}!\idxcode{optional}}% \begin{itemdecl} -template struct hash>; +template struct hash>; \end{itemdecl} \begin{itemdescr} @@ -3755,90 +3676,89 @@ These template arguments are called alternatives. \rSec2[variant.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{variant}}% -\indexlibrary{\idxhdr{variant}}% +\indexhdr{variant}% \begin{codeblock} namespace std { // \ref{variant.variant}, class template \tcode{variant} - template + template class variant; // \ref{variant.helper}, variant helper classes - template struct variant_size; // not defined - template struct variant_size; - template struct variant_size; - template struct variant_size; - template + template struct variant_size; // not defined + template struct variant_size; + template struct variant_size; + template struct variant_size; + template inline constexpr size_t variant_size_v = variant_size::value; - template + template struct variant_size>; - template struct variant_alternative; // not defined - template struct variant_alternative; - template struct variant_alternative; - template struct variant_alternative; - template + template struct variant_alternative; // not defined + template struct variant_alternative; + template struct variant_alternative; + template struct variant_alternative; + template using variant_alternative_t = typename variant_alternative::type; - template + template struct variant_alternative>; inline constexpr size_t variant_npos = -1; // \ref{variant.get}, value access - template + template constexpr bool holds_alternative(const variant&) noexcept; - template + template constexpr variant_alternative_t>& get(variant&); - template + template constexpr variant_alternative_t>&& get(variant&&); - template + template constexpr const variant_alternative_t>& get(const variant&); - template + template constexpr const variant_alternative_t>&& get(const variant&&); - template + template constexpr T& get(variant&); - template + template constexpr T&& get(variant&&); - template + template constexpr const T& get(const variant&); - template + template constexpr const T&& get(const variant&&); - template + template constexpr add_pointer_t>> get_if(variant*) noexcept; - template + template constexpr add_pointer_t>> get_if(const variant*) noexcept; - template + template constexpr add_pointer_t get_if(variant*) noexcept; - template + template constexpr add_pointer_t get_if(const variant*) noexcept; // \ref{variant.relops}, relational operators - template + template constexpr bool operator==(const variant&, const variant&); - template + template constexpr bool operator!=(const variant&, const variant&); - template + template constexpr bool operator<(const variant&, const variant&); - template + template constexpr bool operator>(const variant&, const variant&); - template + template constexpr bool operator<=(const variant&, const variant&); - template + template constexpr bool operator>=(const variant&, const variant&); // \ref{variant.visit}, visitation - template + template constexpr @\seebelow@ visit(Visitor&&, Variants&&...); // \ref{variant.monostate}, class \tcode{monostate} @@ -3853,16 +3773,16 @@ constexpr bool operator!=(monostate, monostate) noexcept; // \ref{variant.specalg}, specialized algorithms - template + template void swap(variant&, variant&) noexcept(@\seebelow@); // \ref{variant.bad.access}, class \tcode{bad_variant_access} class bad_variant_access; // \ref{variant.hash}, hash support - template struct hash; - template struct hash>; - template <> struct hash; + template struct hash; + template struct hash>; + template<> struct hash; } \end{codeblock} @@ -3871,7 +3791,7 @@ \begin{codeblock} namespace std { - template + template class variant { public: // \ref{variant.ctor}, constructors @@ -3879,17 +3799,17 @@ variant(const variant&); variant(variant&&) noexcept(@\seebelow@); - template + template constexpr variant(T&&) noexcept(@\seebelow@); - template + template constexpr explicit variant(in_place_type_t, Args&&...); - template + template constexpr explicit variant(in_place_type_t, initializer_list, Args&&...); - template + template constexpr explicit variant(in_place_index_t, Args&&...); - template + template constexpr explicit variant(in_place_index_t, initializer_list, Args&&...); // \ref{variant.dtor}, destructor @@ -3899,16 +3819,16 @@ variant& operator=(const variant&); variant& operator=(variant&&) noexcept(@\seebelow@); - template variant& operator=(T&&) noexcept(@\seebelow@); + template variant& operator=(T&&) noexcept(@\seebelow@); // \ref{variant.mod}, modifiers - template + template T& emplace(Args&&...); - template + template T& emplace(initializer_list, Args&&...); - template + template variant_alternative_t>& emplace(Args&&...); - template + template variant_alternative_t>& emplace(initializer_list, Args&&...); // \ref{variant.status}, value status @@ -3998,7 +3918,7 @@ \pnum \remarks -This function shall not participate in overload resolution unless +This constructor shall be defined as deleted unless \tcode{is_copy_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. \end{itemdescr} @@ -4029,7 +3949,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -template constexpr variant(T&& t) noexcept(@\seebelow@); +template constexpr variant(T&& t) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -4056,16 +3976,27 @@ \pnum \remarks -This function shall not participate in overload resolution -unless \tcode{sizeof...(Types)} is nonzero, -unless \tcode{is_same_v, variant>} is \tcode{false}, -unless \tcode{decay_t} is neither -a specialization of \tcode{in_place_type_t} -nor a specialization of \tcode{in_place_index_t}, -unless \tcode{is_constructible_v<$\tcode{T}_j$, T>} is \tcode{true}, -and unless the expression -\tcode{\placeholdernc{FUN}(}\brk\tcode{std::forward(t))} (with \tcode{\placeholdernc{FUN}} -being the above-mentioned set of imaginary functions) is well-formed. +This function shall not participate in overload resolution unless +\begin{itemize} +\item + \tcode{sizeof...(Types)} is nonzero, + +\item + \tcode{is_same_v, variant>} is \tcode{false}, + +\item + \tcode{remove_cvref_t} is neither a specialization + of \tcode{in_place_type_t} nor a specialization + of \tcode{in_place_index_t}, + +\item + \tcode{is_constructible_v<$\tcode{T}_j$, T>} is \tcode{true}, and + +\item + the expression \tcode{\placeholdernc{FUN}(}\brk\tcode{std::forward(t))} + (with \tcode{\placeholdernc{FUN}} being the above-mentioned set of + imaginary functions) is well-formed. +\end{itemize} \pnum \begin{note} @@ -4084,7 +4015,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -template constexpr explicit variant(in_place_type_t, Args&&... args); +template constexpr explicit variant(in_place_type_t, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4113,7 +4044,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -template +template constexpr explicit variant(in_place_type_t, initializer_list il, Args&&... args); \end{itemdecl} @@ -4143,7 +4074,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -template constexpr explicit variant(in_place_index_t, Args&&... args); +template constexpr explicit variant(in_place_index_t, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4176,7 +4107,7 @@ \indexlibrary{\idxcode{variant}!constructor}% \begin{itemdecl} -template +template constexpr explicit variant(in_place_index_t, initializer_list il, Args&&... args); \end{itemdecl} @@ -4238,19 +4169,20 @@ \effects \begin{itemize} \item -If neither \tcode{*this} nor \tcode{rhs} holds a value, there is no effect. Otherwise, +If neither \tcode{*this} nor \tcode{rhs} holds a value, there is no effect. \item -if \tcode{*this} holds a value but \tcode{rhs} does not, destroys the value -contained in \tcode{*this} and sets \tcode{*this} to not hold a value. Otherwise, +Otherwise, if \tcode{*this} holds a value but \tcode{rhs} does not, destroys the value +contained in \tcode{*this} and sets \tcode{*this} to not hold a value. \item -if \tcode{index() == $j$}, assigns the value contained in \tcode{rhs} -to the value contained in \tcode{*this}. Otherwise, +Otherwise, if \tcode{index() == $j$}, assigns the value contained in \tcode{rhs} +to the value contained in \tcode{*this}. \item -if either \tcode{is_nothrow_copy_constructible_v<$\tcode{T}_j$>} or -\tcode{!is_nothrow_move_constructible_v<$\tcode{T}_j$>} is \tcode{true}, -equivalent to \tcode{emplace<$j$>(get<$j$>(rhs))}. Otherwise, +Otherwise, if either \tcode{is_nothrow_copy_constructible_v<$\tcode{T}_j$>} +is \tcode{true} or +\tcode{is_nothrow_move_con\-structible_v<$\tcode{T}_j$>} is \tcode{false}, +equivalent to \tcode{emplace<$j$>(get<$j$>(rhs))}. \item -equivalent to \tcode{operator=(variant(rhs))}. +Otherwise, equivalent to \tcode{operator=(variant(rhs))}. \end{itemize} \pnum @@ -4261,7 +4193,7 @@ \pnum \remarks -This function shall not participate in overload resolution unless +This operator shall be defined as deleted unless \tcode{is_copy_constructible_v<$\tcode{T}_i$> \&\&} \tcode{is_copy_assignable_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. @@ -4280,15 +4212,15 @@ \effects \begin{itemize} \item -If neither \tcode{*this} nor \tcode{rhs} holds a value, there is no effect. Otherwise, +If neither \tcode{*this} nor \tcode{rhs} holds a value, there is no effect. \item -if \tcode{*this} holds a value but \tcode{rhs} does not, destroys the value -contained in \tcode{*this} and sets \tcode{*this} to not hold a value. Otherwise, +Otherwise, if \tcode{*this} holds a value but \tcode{rhs} does not, destroys the value +contained in \tcode{*this} and sets \tcode{*this} to not hold a value. \item -if \tcode{index() == $j$}, assigns \tcode{get<$j$>(std::move(rhs))} to -the value contained in \tcode{*this}. Otherwise, +Otherwise, if \tcode{index() == $j$}, assigns \tcode{get<$j$>(std::move(rhs))} to +the value contained in \tcode{*this}. \item -equivalent to \tcode{emplace<$j$>(get<$j$>(std::move(rhs)))}. +Otherwise, equivalent to \tcode{emplace<$j$>(get<$j$>(std::move(rhs)))}. \end{itemize} \pnum @@ -4312,7 +4244,7 @@ \indexlibrarymember{operator=}{variant}% \begin{itemdecl} -template variant& operator=(T&& t) noexcept(@\seebelow@); +template variant& operator=(T&& t) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -4329,13 +4261,13 @@ \begin{itemize} \item If \tcode{*this} holds a $\tcode{T}_j$, assigns \tcode{std::forward(t)} to -the value contained in \tcode{*this}. Otherwise, +the value contained in \tcode{*this}. \item -if \tcode{is_nothrow_constructible_v<$\tcode{T}_j$, T> ||} +Otherwise, if \tcode{is_nothrow_constructible_v<$\tcode{T}_j$, T> ||} \tcode{!is_nothrow_move_constructible_v<$\tcode{T}_j$>} is \tcode{true}, -equivalent to \tcode{emplace<$j$>(std::forward(t))}. Otherwise, +equivalent to \tcode{emplace<$j$>(std::forward(t))}. \item -equivalent to \tcode{operator=(variant(std::forward(t)))}. +Otherwise, equivalent to \tcode{operator=(variant(std::forward(t)))}. \end{itemize} \pnum @@ -4349,11 +4281,19 @@ \pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_same_v, variant>} is \tcode{false}, unless -\tcode{is_assignable_v<$\tcode{T}_j$\&, T> \&\& is_constructible_v<$\tcode{T}_j$, T>} is \tcode{true}, -and unless the expression \tcode{\placeholdernc{FUN}(std::forward(t))} (with -\tcode{\placeholdernc{FUN}} being the above-mentioned set of imaginary functions) -is well-formed. +\begin{itemize} +\item + \tcode{is_same_v, variant>} is \tcode{false}, + +\item + \tcode{is_assignable_v<$\tcode{T}_j$\&, T> \&\& is_constructible_v<$\tcode{T}_j$, T>} + is \tcode{true}, and + +\item + the expression \tcode{\placeholdernc{FUN}(std::forward(t))} + (with \tcode{\placeholdernc{FUN}} being the above-mentioned set + of imaginary functions) is well-formed. +\end{itemize} \pnum \begin{note} @@ -4383,7 +4323,7 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template T& emplace(Args&&... args); +template T& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4403,7 +4343,7 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template T& emplace(initializer_list il, Args&&... args); +template T& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4423,7 +4363,7 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template +template variant_alternative_t>& emplace(Args&&... args); \end{itemdecl} @@ -4462,7 +4402,7 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template +template variant_alternative_t>& emplace(initializer_list il, Args&&... args); \end{itemdecl} @@ -4553,11 +4493,11 @@ \effects \begin{itemize} \item -if \tcode{valueless_by_exception() \&\& rhs.valueless_by_exception()} no effect. Otherwise, +If \tcode{valueless_by_exception() \&\& rhs.valueless_by_exception()} no effect. \item -if \tcode{index() == rhs.index()}, calls \tcode{swap(get<$i$>(*this), get<$i$>(rhs))} where $i$ is \tcode{index()}. Otherwise, +Otherwise, if \tcode{index() == rhs.index()}, calls \tcode{swap(get<$i$>(*this), get<$i$>(rhs))} where $i$ is \tcode{index()}. \item -exchanges values of \tcode{rhs} and \tcode{*this}. +Otherwise, exchanges values of \tcode{rhs} and \tcode{*this}. \end{itemize} \pnum @@ -4586,7 +4526,7 @@ \indexlibrary{\idxcode{variant_size}}% \begin{itemdecl} -template struct variant_size; +template struct variant_size; \end{itemdecl} \begin{itemdescr} @@ -4599,9 +4539,9 @@ \indexlibrary{\idxcode{variant_size}}% \begin{itemdecl} -template class variant_size; -template class variant_size; -template class variant_size; +template class variant_size; +template class variant_size; +template class variant_size; \end{itemdecl} \begin{itemdescr} @@ -4614,16 +4554,16 @@ \indexlibrary{\idxcode{variant_size}}% \begin{itemdecl} -template +template struct variant_size> : integral_constant { }; \end{itemdecl} % No itemdescr needed for variant_size> \indexlibrary{\idxcode{variant_alternative}}% \begin{itemdecl} -template class variant_alternative; -template class variant_alternative; -template class variant_alternative; +template class variant_alternative; +template class variant_alternative; +template class variant_alternative; \end{itemdecl} \begin{itemdescr} @@ -4658,7 +4598,7 @@ \indexlibrary{\idxcode{holds_alternative}} \indexlibrary{\idxcode{variant}!\idxcode{holds_alternative}} \begin{itemdecl} -template +template constexpr bool holds_alternative(const variant& v) noexcept; \end{itemdecl} @@ -4675,13 +4615,13 @@ \indexlibrarymember{get}{variant}% \begin{itemdecl} -template +template constexpr variant_alternative_t>& get(variant& v); -template +template constexpr variant_alternative_t>&& get(variant&& v); -template +template constexpr const variant_alternative_t>& get(const variant& v); -template +template constexpr const variant_alternative_t>&& get(const variant&& v); \end{itemdecl} @@ -4699,10 +4639,10 @@ \indexlibrarymember{get}{variant}% \begin{itemdecl} -template constexpr T& get(variant& v); -template constexpr T&& get(variant&& v); -template constexpr const T& get(const variant& v); -template constexpr const T&& get(const variant&& v); +template constexpr T& get(variant& v); +template constexpr T&& get(variant&& v); +template constexpr const T& get(const variant& v); +template constexpr const T&& get(const variant&& v); \end{itemdecl} \begin{itemdescr} @@ -4720,10 +4660,10 @@ \indexlibrary{\idxcode{get_if}}% \indexlibrary{\idxcode{variant}!\idxcode{get_if}}% \begin{itemdecl} -template +template constexpr add_pointer_t>> get_if(variant* v) noexcept; -template +template constexpr add_pointer_t>> get_if(const variant* v) noexcept; \end{itemdecl} @@ -4743,10 +4683,10 @@ \indexlibrary{\idxcode{get_if}}% \indexlibrary{\idxcode{variant}!\idxcode{get_if}}% \begin{itemdecl} -template +template constexpr add_pointer_t get_if(variant* v) noexcept; -template +template constexpr add_pointer_t get_if(const variant* v) noexcept; \end{itemdecl} @@ -4767,7 +4707,7 @@ \indexlibrarymember{operator==}{variant}% \begin{itemdecl} -template +template constexpr bool operator==(const variant& v, const variant& w); \end{itemdecl} @@ -4786,7 +4726,7 @@ \indexlibrarymember{operator"!=}{variant}% \begin{itemdecl} -template +template constexpr bool operator!=(const variant& v, const variant& w); \end{itemdecl} @@ -4805,7 +4745,7 @@ \indexlibrarymember{operator<}{variant}% \begin{itemdecl} -template +template constexpr bool operator<(const variant& v, const variant& w); \end{itemdecl} @@ -4826,7 +4766,7 @@ \indexlibrarymember{operator>}{variant}% \begin{itemdecl} -template +template constexpr bool operator>(const variant& v, const variant& w); \end{itemdecl} @@ -4847,7 +4787,7 @@ \indexlibrarymember{operator<=}{variant}% \begin{itemdecl} -template +template constexpr bool operator<=(const variant& v, const variant& w); \end{itemdecl} @@ -4868,7 +4808,7 @@ \indexlibrarymember{operator>=}{variant}% \begin{itemdecl} -template +template constexpr bool operator>=(const variant& v, const variant& w); \end{itemdecl} @@ -4892,7 +4832,7 @@ \indexlibrary{\idxcode{visit}}% \indexlibrary{\idxcode{variant}!\idxcode{visit}}% \begin{itemdecl} -template +template constexpr @\seebelow@ visit(Visitor&& vis, Variants&&... vars); \end{itemdecl} @@ -4920,7 +4860,7 @@ \pnum \complexity For \tcode{sizeof...(Variants) <= 1}, the invocation of the callable object is -implemented in constant time, i.e. it does not depend on \tcode{sizeof...(Types).} +implemented in constant time, i.e., it does not depend on \tcode{sizeof...(Types).} For \tcode{sizeof...(Variants) > 1}, the invocation of the callable object has no complexity requirements. \end{itemdescr} @@ -4966,7 +4906,7 @@ \indexlibrary{\idxcode{swap}!\idxcode{variant}}% \begin{itemdecl} -template +template void swap(variant& v, variant& w) noexcept(@\seebelow@); \end{itemdecl} @@ -5013,14 +4953,14 @@ \begin{itemdescr} \pnum -\returns An \impldef{return value of \tcode{bad_variant_access::what}} \ntbs. +\returns An \impldef{return value of \tcode{bad_variant_access::what}} \ntbs{}. \end{itemdescr} \rSec2[variant.hash]{Hash support} \indexlibrary{\idxcode{hash}!\idxcode{variant}}% \begin{itemdecl} -template struct hash>; +template struct hash>; \end{itemdecl} \begin{itemdescr} @@ -5032,7 +4972,7 @@ \indexlibrary{\idxcode{hash}!\idxcode{monostate}}% \begin{itemdecl} -template <> struct hash; +template<> struct hash; \end{itemdecl} \begin{itemdescr} @@ -5044,19 +4984,18 @@ \rSec1[any]{Storage for any type} \pnum -This section describes components that \Cpp programs may use to perform operations on objects of a discriminated type. +This subclause describes components that \Cpp{} programs may use to perform operations on objects of a discriminated type. \pnum \begin{note} The discriminated type may contain values of different types but does not attempt conversion between them, -i.e. \tcode{5} is held strictly as an \tcode{int} and is not implicitly convertible either to \tcode{"5"} or to \tcode{5.0}. +i.e., \tcode{5} is held strictly as an \tcode{int} and is not implicitly convertible either to \tcode{"5"} or to \tcode{5.0}. This indifference to interpretation but awareness of type effectively allows safe, generic containers of single values, with no scope for surprises from ambiguous conversions. \end{note} \rSec2[any.synop]{Header \tcode{} synopsis} -\indextext{\idxhdr{any}}% -\indexlibrary{\idxhdr{any}}% +\indexhdr{any}% \begin{codeblock} namespace std { @@ -5069,9 +5008,9 @@ // \ref{any.nonmembers}, non-member functions void swap(any& x, any& y) noexcept; - template + template any make_any(Args&& ...args); - template + template any make_any(initializer_list il, Args&& ...args); template @@ -5108,7 +5047,7 @@ \begin{itemdescr} \pnum -\returns An \impldef{return value of \tcode{bad_any_cast::what}} \ntbs. +\returns An \impldef{return value of \tcode{bad_any_cast::what}} \ntbs{}. \pnum \remarks @@ -5127,11 +5066,11 @@ any(const any& other); any(any&& other) noexcept; - template any(T&& value); + template any(T&& value); - template + template explicit any(in_place_type_t, Args&&...); - template + template explicit any(in_place_type_t, initializer_list, Args&&...); ~any(); @@ -5140,12 +5079,12 @@ any& operator=(const any& rhs); any& operator=(any&& rhs) noexcept; - template any& operator=(T&& rhs); + template any& operator=(T&& rhs); // \ref{any.modifiers}, modifiers - template + template decay_t& emplace(Args&& ...); - template + template decay_t& emplace(initializer_list, Args&&...); void reset() noexcept; void swap(any& rhs) noexcept; @@ -5159,7 +5098,7 @@ \pnum An object of class \tcode{any} stores an instance of any type that satisfies the constructor requirements or it has no value, and this is referred to as the \defn{state} of the class \tcode{any} object. -The stored instance is called the \defnx{contained value}{contained value!\idxcode{any}}, +The stored instance is called the \defnx{contained value}{contained value!\idxcode{any}}. Two states are equivalent if either they both have no value, or both have a value and the contained values are equivalent. \pnum @@ -5254,7 +5193,7 @@ \indexlibrary{\idxcode{any}!constructor}% \begin{itemdecl} -template +template explicit any(in_place_type_t, Args&&... args); \end{itemdecl} @@ -5284,7 +5223,7 @@ \indexlibrary{\idxcode{any}!constructor}% \begin{itemdecl} -template +template explicit any(in_place_type_t, initializer_list il, Args&&... args); \end{itemdecl} @@ -5403,7 +5342,7 @@ \indexlibrarymember{emplace}{any}% \begin{itemdecl} -template +template decay_t& emplace(Args&&... args); \end{itemdecl} @@ -5441,7 +5380,7 @@ \indexlibrarymember{emplace}{any}% \begin{itemdecl} -template +template decay_t& emplace(initializer_list il, Args&&... args); \end{itemdecl} @@ -5549,7 +5488,7 @@ \indexlibrary{\idxcode{make_any}}% \begin{itemdecl} -template +template any make_any(Args&& ...args); \end{itemdecl} @@ -5561,7 +5500,7 @@ \indexlibrary{\idxcode{make_any}}% \begin{itemdecl} -template +template any make_any(initializer_list il, Args&& ...args); \end{itemdecl} @@ -5583,7 +5522,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be the type \tcode{remove_cv_t>}. +Let \tcode{U} be the type \tcode{remove_cvref_t}. \pnum \requires @@ -5661,27 +5600,26 @@ \rSec2[bitset.syn]{Header \tcode{} synopsis}% -\indextext{\idxhdr{bitset}}% -\indexlibrary{\idxhdr{bitset}}% +\indexhdr{bitset}% \begin{codeblock} #include #include // for \tcode{istream}\iref{istream.syn}, \tcode{ostream}\iref{ostream.syn}, see \ref{iosfwd.syn} namespace std { - template class bitset; + template class bitset; // \ref{bitset.operators}, bitset operators - template + template bitset operator&(const bitset&, const bitset&) noexcept; - template + template bitset operator|(const bitset&, const bitset&) noexcept; - template + template bitset operator^(const bitset&, const bitset&) noexcept; - template + template basic_istream& operator>>(basic_istream& is, bitset& x); - template + template basic_ostream& operator<<(basic_ostream& os, const bitset& x); } @@ -5701,7 +5639,7 @@ namespace std { template class bitset { public: - // bit reference: + // bit reference class reference { friend class bitset; reference() noexcept; @@ -5726,7 +5664,7 @@ = basic_string::npos, charT zero = charT('0'), charT one = charT('1')); - template + template explicit bitset( const charT* str, typename basic_string::size_type n = basic_string::npos, @@ -5747,13 +5685,13 @@ bitset& flip() noexcept; bitset& flip(size_t pos); - // element access: + // element access constexpr bool operator[](size_t pos) const; // for \tcode{b[i];} reference operator[](size_t pos); // for \tcode{b[i];} unsigned long to_ulong() const; unsigned long long to_ullong() const; - template , class Allocator = allocator> basic_string @@ -5772,8 +5710,8 @@ }; // \ref{bitset.hash}, hash support - template struct hash; - template struct hash>; + template struct hash; + template struct hash>; } \end{codeblock} @@ -5859,7 +5797,7 @@ \indexlibrary{\idxcode{bitset}!constructor}% \begin{itemdecl} -template +template explicit bitset( const basic_string& str, typename basic_string::size_type pos = 0, @@ -5915,7 +5853,7 @@ \indexlibrary{\idxcode{bitset}!constructor}% \begin{itemdecl} -template +template explicit bitset( const charT* str, typename basic_string::size_type n = basic_string::npos, @@ -6215,7 +6153,7 @@ \indexlibrarymember{to_string}{bitset}% \begin{itemdecl} -template , class Allocator = allocator> basic_string @@ -6417,7 +6355,7 @@ \indexlibrary{\idxcode{hash_code}}% \begin{itemdecl} -template struct hash>; +template struct hash>; \end{itemdecl} \begin{itemdescr} @@ -6462,7 +6400,7 @@ \indexlibrarymember{operator>>}{bitset}% \begin{itemdecl} -template +template basic_istream& operator>>(basic_istream& is, bitset& x); \end{itemdecl} @@ -6507,7 +6445,7 @@ \indexlibrarymember{operator<<}{bitset}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream& os, const bitset& x); \end{itemdecl} @@ -6545,18 +6483,23 @@ \tcode{unique_ptr}, \tcode{shared_ptr}, \tcode{weak_ptr}, and various function templates that operate on objects of these types\iref{smartptr}. -\indextext{\idxhdr{memory}}% -\indexlibrary{\idxhdr{memory}}% +\indexhdr{memory}% \begin{codeblock} namespace std { // \ref{pointer.traits}, pointer traits - template struct pointer_traits; - template struct pointer_traits; + template struct pointer_traits; + template struct pointer_traits; + + // \ref{pointer.conversion}, pointer conversion + template + auto to_address(const Ptr& p) noexcept; + template + constexpr T* to_address(T* p) noexcept; // \ref{util.dynamic.safety}, pointer safety enum class pointer_safety { relaxed, preferred, strict }; void declare_reachable(void* p); - template + template T* undeclare_reachable(T* p); void declare_no_pointers(char* p, size_t n); void undeclare_no_pointers(char* p, size_t n); @@ -6570,148 +6513,151 @@ inline constexpr allocator_arg_t allocator_arg{}; // \ref{allocator.uses}, \tcode{uses_allocator} - template struct uses_allocator; + template struct uses_allocator; // \ref{allocator.traits}, allocator traits - template struct allocator_traits; + template struct allocator_traits; // \ref{default.allocator}, the default allocator - template class allocator; - template + template class allocator; + template bool operator==(const allocator&, const allocator&) noexcept; - template + template bool operator!=(const allocator&, const allocator&) noexcept; // \ref{specialized.algorithms}, specialized algorithms - template + template constexpr T* addressof(T& r) noexcept; - template + template const T* addressof(const T&&) = delete; - template + template void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); - template + template void uninitialized_default_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); - template + template ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); - template + template ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); - template + template void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); - template + template void uninitialized_value_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); - template + template ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); - template + template ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); - template + template ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); - template + template ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, InputIterator last, ForwardIterator result); - template + template ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); - template + template ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, Size n, ForwardIterator result); - template + template ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); - template + template ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, InputIterator last, ForwardIterator result); - template + template pair uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); - template + template pair uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} InputIterator first, Size n, ForwardIterator result); - template + template void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); - template + template void uninitialized_fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& x); - template + template ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); - template + template ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, const T& x); - template + template void destroy_at(T* location); - template + template void destroy(ForwardIterator first, ForwardIterator last); - template + template void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); - template + template ForwardIterator destroy_n(ForwardIterator first, Size n); - template + template ForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); // \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 struct default_delete; + template struct default_delete; + template> class unique_ptr; + template class unique_ptr; - template unique_ptr + template unique_ptr make_unique(Args&&... args); // \tcode{T} is not array - template unique_ptr + template unique_ptr make_unique(size_t n); // \tcode{T} is \tcode{U[]} - template + template @\unspecnc@ make_unique(Args&&...) = delete; // \tcode{T} is \tcode{U[N]} - template + template void swap(unique_ptr& x, unique_ptr& y) noexcept; - template + template bool operator==(const unique_ptr& x, const unique_ptr& y); - template + template bool operator!=(const unique_ptr& x, const unique_ptr& y); - template + template bool operator<(const unique_ptr& x, const unique_ptr& y); - template + template bool operator<=(const unique_ptr& x, const unique_ptr& y); - template + template bool operator>(const unique_ptr& x, const unique_ptr& y); - template + template bool operator>=(const unique_ptr& x, const unique_ptr& y); - template + template bool operator==(const unique_ptr& x, nullptr_t) noexcept; - template + template bool operator==(nullptr_t, const unique_ptr& y) noexcept; - template + template bool operator!=(const unique_ptr& x, nullptr_t) noexcept; - template + template bool operator!=(nullptr_t, const unique_ptr& y) noexcept; - template + template bool operator<(const unique_ptr& x, nullptr_t); - template + template bool operator<(nullptr_t, const unique_ptr& y); - template + template bool operator<=(const unique_ptr& x, nullptr_t); - template + template bool operator<=(nullptr_t, const unique_ptr& y); - template + template bool operator>(const unique_ptr& x, nullptr_t); - template + template bool operator>(nullptr_t, const unique_ptr& y); - template + template bool operator>=(const unique_ptr& x, nullptr_t); - template + template bool operator>=(nullptr_t, const unique_ptr& y); + template + basic_ostream& operator<<(basic_ostream& os, const unique_ptr& p); + // \ref{util.smartptr.weak.bad}, class \tcode{bad_weak_ptr} class bad_weak_ptr; @@ -6759,29 +6705,29 @@ template bool operator>=(const shared_ptr& a, const shared_ptr& b) noexcept; - template + template bool operator==(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator==(nullptr_t, const shared_ptr& y) noexcept; - template + template bool operator!=(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator!=(nullptr_t, const shared_ptr& y) noexcept; - template + template bool operator<(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator<(nullptr_t, const shared_ptr& y) noexcept; - template + template bool operator<=(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator<=(nullptr_t, const shared_ptr& y) noexcept; - template + template bool operator>(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator>(nullptr_t, const shared_ptr& y) noexcept; - template + template bool operator>=(const shared_ptr& x, nullptr_t) noexcept; - template + template bool operator>=(nullptr_t, const shared_ptr& y) noexcept; // \ref{util.smartptr.shared.spec}, \tcode{shared_ptr} specialized algorithms @@ -6818,47 +6764,17 @@ // \ref{util.smartptr.enab}, class template \tcode{enable_shared_from_this} template class enable_shared_from_this; - // \ref{util.smartptr.shared.atomic}, \tcode{shared_ptr} atomic access - template - bool atomic_is_lock_free(const shared_ptr* p); - - template - shared_ptr atomic_load(const shared_ptr* p); - template - shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); - - template - void atomic_store(shared_ptr* p, shared_ptr r); - template - void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); - - template - shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); - template - shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); - - template - bool atomic_compare_exchange_weak( - shared_ptr* p, shared_ptr* v, shared_ptr w); - template - bool atomic_compare_exchange_strong( - shared_ptr* p, shared_ptr* v, shared_ptr w); - template - bool atomic_compare_exchange_weak_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); - template - bool atomic_compare_exchange_strong_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); - // \ref{util.smartptr.hash}, hash support - template struct hash; - template struct hash>; - template struct hash>; + template struct hash; + template struct hash>; + template struct hash>; + + // \ref{util.smartptr.atomic}, atomic smart pointers + template struct atomic>; + template struct atomic>; // \ref{allocator.uses.trait}, \tcode{uses_allocator} - template + template inline constexpr bool uses_allocator_v = uses_allocator::value; } \end{codeblock} @@ -6872,22 +6788,22 @@ \indexlibrary{\idxcode{pointer_traits}}% \begin{codeblock} namespace std { - template struct pointer_traits { + template struct pointer_traits { using pointer = Ptr; using element_type = @\seebelow@; using difference_type = @\seebelow@; - template using rebind = @\seebelow@; + template using rebind = @\seebelow@; static pointer pointer_to(@\seebelow@ r); }; - template struct pointer_traits { + template struct pointer_traits { using pointer = T*; using element_type = T; using difference_type = ptrdiff_t; - template using rebind = U*; + template using rebind = U*; static pointer pointer_to(@\seebelow@ r) noexcept; }; @@ -6926,7 +6842,7 @@ \indexlibrarymember{rebind}{pointer_traits}% \begin{itemdecl} -template using rebind = @\seebelow@; +template using rebind = @\seebelow@; \end{itemdecl} \begin{itemdescr} @@ -6961,6 +6877,60 @@ function. The second member function returns \tcode{addressof(r)}. \end{itemdescr} +\rSec3[pointer.traits.optmem]{Pointer traits optional members} + +\pnum +Specializations of \tcode{pointer_traits} may define the member declared +in this subclause to customize the behavior of the standard library. + +\indexlibrarymember{to_address}{pointer_traits}% +\begin{itemdecl} +static element_type* to_address(pointer p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer of type \tcode{element_type*} that references +the same location as the argument \tcode{p}. + +\pnum +\begin{note} +This function should be the inverse of \tcode{pointer_to}. +If defined, it customizes the behavior of +the non-member function +\tcode{to_address}\iref{pointer.conversion}. +\end{note} +\end{itemdescr} + +\rSec2[pointer.conversion]{Pointer conversion} + +\indexlibrary{\idxcode{to_address}}% +\begin{itemdecl} +template auto to_address(const Ptr& p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{pointer_traits::to_address(p)} if that expression is well-formed +(see \ref{pointer.traits.optmem}), +otherwise \tcode{to_address(p.operator->())}. +\end{itemdescr} + +\indexlibrary{\idxcode{to_address}}% +\begin{itemdecl} +template constexpr T* to_address(T* p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{T} is not a function type. Otherwise the program is ill-formed. + +\pnum +\returns \tcode{p}. +\end{itemdescr} + \rSec2[util.dynamic.safety]{Pointer safety} \pnum @@ -6990,7 +6960,7 @@ \indexlibrary{\idxcode{undeclare_reachable}}% \begin{itemdecl} -template T* undeclare_reachable(T* p); +template T* undeclare_reachable(T* p); \end{itemdecl} \begin{itemdescr} @@ -7145,7 +7115,7 @@ \indexlibrary{\idxcode{uses_allocator}}% \begin{itemdecl} -template struct uses_allocator; +template struct uses_allocator; \end{itemdecl} \begin{itemdescr} @@ -7209,7 +7179,7 @@ \indexlibrary{\idxcode{allocator_traits}}% \begin{codeblock} namespace std { - template struct allocator_traits { + template struct allocator_traits { using allocator_type = Alloc; using value_type = typename Alloc::value_type; @@ -7227,18 +7197,18 @@ using propagate_on_container_swap = @\seebelow@; using is_always_equal = @\seebelow@; - template using rebind_alloc = @\seebelow@; - template using rebind_traits = allocator_traits>; + template using rebind_alloc = @\seebelow@; + template using rebind_traits = allocator_traits>; - static pointer allocate(Alloc& a, size_type n); - static pointer allocate(Alloc& a, size_type n, const_void_pointer hint); + [[nodiscard]] static pointer allocate(Alloc& a, size_type n); + [[nodiscard]] static pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static void deallocate(Alloc& a, pointer p, size_type n); - template + template static void construct(Alloc& a, T* p, Args&&... args); - template + template static void destroy(Alloc& a, T* p); static size_type max_size(const Alloc& a) noexcept; @@ -7381,7 +7351,7 @@ \indexlibrarymember{rebind_alloc}{allocator_traits}% \begin{itemdecl} -template using rebind_alloc = @\seebelow@; +template using rebind_alloc = @\seebelow@; \end{itemdecl} \begin{itemdescr} @@ -7398,7 +7368,7 @@ \indexlibrarymember{allocate}{allocator_traits}% \begin{itemdecl} -static pointer allocate(Alloc& a, size_type n); +[[nodiscard]] static pointer allocate(Alloc& a, size_type n); \end{itemdecl} \begin{itemdescr} @@ -7408,7 +7378,7 @@ \indexlibrarymember{allocate}{allocator_traits}% \begin{itemdecl} -static pointer allocate(Alloc& a, size_type n, const_void_pointer hint); +[[nodiscard]] static pointer allocate(Alloc& a, size_type n, const_void_pointer hint); \end{itemdecl} \begin{itemdescr} @@ -7431,7 +7401,7 @@ \indexlibrarymember{construct}{allocator_traits}% \begin{itemdecl} -template +template static void construct(Alloc& a, T* p, Args&&... args); \end{itemdecl} @@ -7444,7 +7414,7 @@ \indexlibrarymember{destroy}{allocator_traits}% \begin{itemdecl} -template +template static void destroy(Alloc& a, T* p); \end{itemdecl} @@ -7483,9 +7453,12 @@ allocator completeness requirements\iref{allocator.requirements.completeness}. \indexlibrary{\idxcode{allocator}}% +\indexlibrarymember{value_type}{allocator}% +\indexlibrarymember{propagate_on_container_move_assignment}{allocator}% +\indexlibrarymember{is_always_equal}{allocator}% \begin{codeblock} namespace std { - template class allocator { + template class allocator { public: using value_type = T; using propagate_on_container_move_assignment = true_type; @@ -7493,10 +7466,10 @@ allocator() noexcept; allocator(const allocator&) noexcept; - template allocator(const allocator&) noexcept; + template allocator(const allocator&) noexcept; ~allocator(); - T* allocate(size_t n); + [[nodiscard]] T* allocate(size_t n); void deallocate(T* p, size_t n); }; } @@ -7513,7 +7486,7 @@ \indexlibrarymember{allocate}{allocator}% \begin{itemdecl} -T* allocate(size_t n); +[[nodiscard]] T* allocate(size_t n); \end{itemdecl} \begin{itemdescr} @@ -7561,7 +7534,7 @@ \indexlibrarymember{operator==}{allocator}% \begin{itemdecl} -template +template bool operator==(const allocator&, const allocator&) noexcept; \end{itemdecl} @@ -7573,7 +7546,7 @@ \indexlibrarymember{operator"!=}{allocator}% \begin{itemdecl} -template +template bool operator!=(const allocator&, const allocator&) noexcept; \end{itemdecl} @@ -7607,7 +7580,7 @@ \indexlibrary{\idxcode{addressof}}% \begin{itemdecl} -template constexpr T* addressof(T& r) noexcept; +template constexpr T* addressof(T& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -7625,7 +7598,7 @@ \indexlibrary{\idxcode{uninitialized_default_construct}}% \begin{itemdecl} -template +template void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); \end{itemdecl} @@ -7642,7 +7615,7 @@ \indexlibrary{\idxcode{uninitialized_default_construct_n}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); \end{itemdecl} @@ -7662,7 +7635,7 @@ \indexlibrary{\idxcode{uninitialized_value_construct}}% \begin{itemdecl} -template +template void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); \end{itemdecl} @@ -7679,7 +7652,7 @@ \indexlibrary{\idxcode{uninitialized_value_construct_n}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); \end{itemdecl} @@ -7699,7 +7672,7 @@ \indexlibrary{\idxcode{uninitialized_copy}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); \end{itemdecl} @@ -7721,7 +7694,7 @@ \indexlibrary{\idxcode{uninitialized_copy_n}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); \end{itemdecl} @@ -7744,7 +7717,7 @@ \indexlibrary{\idxcode{uninitialized_move}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); \end{itemdecl} @@ -7768,7 +7741,7 @@ \indexlibrary{\idxcode{uninitialized_move_n}}% \begin{itemdecl} -template +template pair uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); \end{itemdecl} @@ -7794,7 +7767,7 @@ \indexlibrary{\idxcode{uninitialized_fill}}% \begin{itemdecl} -template +template void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); \end{itemdecl} @@ -7811,7 +7784,7 @@ \indexlibrary{\idxcode{uninitialized_fill_n}}% \begin{itemdecl} -template +template ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); \end{itemdecl} @@ -7831,7 +7804,7 @@ \indexlibrary{\idxcode{destroy_at}}% \begin{itemdecl} -template +template void destroy_at(T* location); \end{itemdecl} @@ -7846,7 +7819,7 @@ \indexlibrary{\idxcode{destroy}}% \begin{itemdecl} -template +template void destroy(ForwardIterator first, ForwardIterator last); \end{itemdecl} @@ -7862,7 +7835,7 @@ \indexlibrary{\idxcode{destroy_n}}% \begin{itemdecl} -template +template ForwardIterator destroy_n(ForwardIterator first, Size n); \end{itemdecl} @@ -7880,7 +7853,7 @@ \rSec2[c.malloc]{C library memory allocation} \pnum -\indextext{\idxhdr{cstdlib}}% +\indexhdr{cstdlib}% \begin{note} The header \tcode{}\iref{cstdlib.syn} declares the functions described in this subclause. @@ -8016,9 +7989,9 @@ \begin{codeblock} namespace std { - template struct default_delete { + template struct default_delete { constexpr default_delete() noexcept = default; - template default_delete(const default_delete&) noexcept; + template default_delete(const default_delete&) noexcept; void operator()(T*) const; }; } @@ -8026,7 +7999,7 @@ \indexlibrary{\idxcode{default_delete}!constructor}% \begin{itemdecl} -template default_delete(const default_delete& other) noexcept; +template default_delete(const default_delete& other) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8056,17 +8029,17 @@ \begin{codeblock} namespace std { - template struct default_delete { + template struct default_delete { constexpr default_delete() noexcept = default; - template default_delete(const default_delete&) noexcept; - template void operator()(U* ptr) const; + template default_delete(const default_delete&) noexcept; + template void operator()(U* ptr) const; }; } \end{codeblock} \indexlibrary{\idxcode{default_delete}!constructor} \begin{itemdecl} -template default_delete(const default_delete& other) noexcept; +template default_delete(const default_delete& other) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8082,7 +8055,7 @@ \indexlibrarymember{operator()}{default_delete}% \begin{itemdecl} -template void operator()(U* ptr) const; +template void operator()(U* ptr) const; \end{itemdecl} \begin{itemdescr} @@ -8101,7 +8074,7 @@ \indexlibrary{\idxcode{unique_ptr}}% \begin{codeblock} namespace std { - template > class unique_ptr { + template> class unique_ptr { public: using pointer = @\seebelow@; using element_type = T; @@ -8114,7 +8087,7 @@ unique_ptr(pointer p, @\seebelow@ d2) noexcept; unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; - template + template unique_ptr(unique_ptr&& u) noexcept; // \ref{unique.ptr.single.dtor}, destructor @@ -8122,7 +8095,7 @@ // \ref{unique.ptr.single.asgn}, assignment unique_ptr& operator=(unique_ptr&& u) noexcept; - template + template unique_ptr& operator=(unique_ptr&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; @@ -8268,6 +8241,14 @@ unique_ptr(pointer p, const A&& d) = delete; \end{codeblock} +\pnum +\requires For the first constructor, if \tcode{D} is not a reference type, +\tcode{D} shall satisfy the requirements of \tcode{CopyConstructible} and +such construction shall not exit via an exception. +For the second constructor, if \tcode{D} is not a reference type, +\tcode{D} shall satisfy the requirements of \tcode{MoveConstructible} and +such construction shall not exit via an exception. + \pnum \effects Constructs a \tcode{unique_ptr} object which owns \tcode{p}, initializing the stored pointer with \tcode{p} and initializing the deleter @@ -8333,7 +8314,7 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} -template unique_ptr(unique_ptr&& u) noexcept; +template unique_ptr(unique_ptr&& u) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8417,7 +8398,7 @@ \indexlibrarymember{operator=}{unique_ptr}% \begin{itemdecl} -template unique_ptr& operator=(unique_ptr&& u) noexcept; +template unique_ptr& operator=(unique_ptr&& u) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8587,7 +8568,7 @@ \indexlibrary{\idxcode{unique_ptr}}% \begin{codeblock} namespace std { - template class unique_ptr { + template class unique_ptr { public: using pointer = @\seebelow@; using element_type = T; @@ -8595,11 +8576,11 @@ // \ref{unique.ptr.runtime.ctor}, constructors constexpr unique_ptr() noexcept; - template explicit unique_ptr(U p) noexcept; - template unique_ptr(U p, @\seebelow@ d) noexcept; - template unique_ptr(U p, @\seebelow@ d) noexcept; + template explicit unique_ptr(U p) noexcept; + template unique_ptr(U p, @\seebelow@ d) noexcept; + template unique_ptr(U p, @\seebelow@ d) noexcept; unique_ptr(unique_ptr&& u) noexcept; - template + template unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; @@ -8608,7 +8589,7 @@ // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; - template + template unique_ptr& operator=(unique_ptr&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; @@ -8621,7 +8602,7 @@ // \ref{unique.ptr.runtime.modifiers}, modifiers pointer release() noexcept; - template void reset(U p) noexcept; + template void reset(U p) noexcept; void reset(nullptr_t = nullptr) noexcept; void swap(unique_ptr& u) noexcept; @@ -8665,7 +8646,7 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} -template explicit unique_ptr(U p) noexcept; +template explicit unique_ptr(U p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8686,8 +8667,8 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} -template unique_ptr(U p, @\seebelow@ d) noexcept; -template unique_ptr(U p, @\seebelow@ d) noexcept; +template unique_ptr(U p, @\seebelow@ d) noexcept; +template unique_ptr(U p, @\seebelow@ d) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8709,7 +8690,7 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} -template unique_ptr(unique_ptr&& u) noexcept; +template unique_ptr(unique_ptr&& u) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8737,7 +8718,7 @@ \indexlibrarymember{operator=}{unique_ptr}% \begin{itemdecl} -template unique_ptr& operator=(unique_ptr&& u)noexcept; +template unique_ptr& operator=(unique_ptr&& u)noexcept; \end{itemdecl} \begin{itemdescr} @@ -8791,7 +8772,7 @@ \indexlibrarymember{reset}{unique_ptr}% \begin{itemdecl} -template void reset(U p) noexcept; +template void reset(U p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8813,7 +8794,7 @@ \indexlibrary{\idxcode{make_unique}}% \begin{itemdecl} -template unique_ptr make_unique(Args&&... args); +template unique_ptr make_unique(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -8827,7 +8808,7 @@ \indexlibrary{\idxcode{make_unique}}% \begin{itemdecl} -template unique_ptr make_unique(size_t n); +template unique_ptr make_unique(size_t n); \end{itemdecl} \begin{itemdescr} @@ -8841,7 +8822,7 @@ \indexlibrary{\idxcode{make_unique}}% \begin{itemdecl} -template @\unspec@ make_unique(Args&&...) = delete; +template @\unspec@ make_unique(Args&&...) = delete; \end{itemdecl} \begin{itemdescr} @@ -8854,7 +8835,7 @@ \indexlibrary{\idxcode{swap(unique_ptr\&, unique_ptr\&)}}% \begin{itemdecl} -template void swap(unique_ptr& x, unique_ptr& y) noexcept; +template void swap(unique_ptr& x, unique_ptr& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8868,7 +8849,7 @@ \indexlibrarymember{operator==}{unique_ptr}% \begin{itemdecl} -template +template bool operator==(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8879,7 +8860,7 @@ \indexlibrarymember{operator"!=}{unique_ptr}% \begin{itemdecl} -template +template bool operator!=(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8890,7 +8871,7 @@ \indexlibrarymember{operator<}{unique_ptr}% \begin{itemdecl} -template +template bool operator<(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8916,7 +8897,7 @@ \indexlibrarymember{operator<=}{unique_ptr}% \begin{itemdecl} -template +template bool operator<=(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8927,7 +8908,7 @@ \indexlibrarymember{operator>}{unique_ptr}% \begin{itemdecl} -template +template bool operator>(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8938,7 +8919,7 @@ \indexlibrarymember{operator>=}{unique_ptr}% \begin{itemdecl} -template +template bool operator>=(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -8949,9 +8930,9 @@ \indexlibrarymember{operator==}{unique_ptr}% \begin{itemdecl} -template +template bool operator==(const unique_ptr& x, nullptr_t) noexcept; -template +template bool operator==(nullptr_t, const unique_ptr& x) noexcept; \end{itemdecl} @@ -8962,9 +8943,9 @@ \indexlibrarymember{operator"!=}{unique_ptr}% \begin{itemdecl} -template +template bool operator!=(const unique_ptr& x, nullptr_t) noexcept; -template +template bool operator!=(nullptr_t, const unique_ptr& x) noexcept; \end{itemdecl} @@ -8975,9 +8956,9 @@ \indexlibrarymember{operator<}{unique_ptr}% \begin{itemdecl} -template +template bool operator<(const unique_ptr& x, nullptr_t); -template +template bool operator<(nullptr_t, const unique_ptr& x); \end{itemdecl} @@ -9001,9 +8982,9 @@ \indexlibrarymember{operator>}{unique_ptr}% \begin{itemdecl} -template +template bool operator>(const unique_ptr& x, nullptr_t); -template +template bool operator>(nullptr_t, const unique_ptr& x); \end{itemdecl} @@ -9016,9 +8997,9 @@ \indexlibrarymember{operator<=}{unique_ptr}% \begin{itemdecl} -template +template bool operator<=(const unique_ptr& x, nullptr_t); -template +template bool operator<=(nullptr_t, const unique_ptr& x); \end{itemdecl} @@ -9031,9 +9012,9 @@ \indexlibrarymember{operator>=}{unique_ptr}% \begin{itemdecl} -template +template bool operator>=(const unique_ptr& x, nullptr_t); -template +template bool operator>=(nullptr_t, const unique_ptr& x); \end{itemdecl} @@ -9044,10 +9025,28 @@ The second function template returns \tcode{!(nullptr < x)}. \end{itemdescr} -\indextext{smart pointers|(}% -\rSec2[util.smartptr]{Shared-ownership pointers} +\rSec3[unique.ptr.io]{\tcode{unique_ptr} I/O} + +\indexlibrarymember{operator<<}{unique_ptr}% +\begin{itemdecl} +template + basic_ostream& operator<<(basic_ostream& os, const unique_ptr& p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{os << p.get();} + +\pnum +\returns \tcode{os}. + +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{os << p.get()} is a valid expression. +\end{itemdescr} -\rSec3[util.smartptr.weak.bad]{Class \tcode{bad_weak_ptr}} +\indextext{smart pointers|(}% +\rSec2[util.smartptr.weak.bad]{Class \tcode{bad_weak_ptr}} \indexlibrary{\idxcode{bad_weak_ptr}}% \begin{codeblock} namespace std { @@ -9070,11 +9069,11 @@ \begin{itemdescr} \pnum\postconditions \tcode{what()} returns an -\impldef{return value of \tcode{bad_weak_ptr::what}} \ntbs. +\impldef{return value of \tcode{bad_weak_ptr::what}} \ntbs{}. \end{itemdescr} -\rSec3[util.smartptr.shared]{Class template \tcode{shared_ptr}} +\rSec2[util.smartptr.shared]{Class template \tcode{shared_ptr}} \pnum \indexlibrary{\idxcode{shared_ptr}}% @@ -9086,7 +9085,7 @@ \begin{codeblock} namespace std { - template class shared_ptr { + template class shared_ptr { public: using element_type = remove_extent_t; using weak_type = weak_ptr; @@ -9094,27 +9093,27 @@ // \ref{util.smartptr.shared.const}, constructors constexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } - template + template explicit shared_ptr(Y* p); - template + template shared_ptr(Y* p, D d); - template + template shared_ptr(Y* p, D d, A a); - template + template shared_ptr(nullptr_t p, D d); - template + template shared_ptr(nullptr_t p, D d, A a); - template + template shared_ptr(const shared_ptr& r, element_type* p) noexcept; shared_ptr(const shared_ptr& r) noexcept; - template + template shared_ptr(const shared_ptr& r) noexcept; shared_ptr(shared_ptr&& r) noexcept; - template + template shared_ptr(shared_ptr&& r) noexcept; - template + template explicit shared_ptr(const weak_ptr& r); - template + template shared_ptr(unique_ptr&& r); // \ref{util.smartptr.shared.dest}, destructor @@ -9122,22 +9121,22 @@ // \ref{util.smartptr.shared.assign}, assignment shared_ptr& operator=(const shared_ptr& r) noexcept; - template + template shared_ptr& operator=(const shared_ptr& r) noexcept; shared_ptr& operator=(shared_ptr&& r) noexcept; - template + template shared_ptr& operator=(shared_ptr&& r) noexcept; - template + template shared_ptr& operator=(unique_ptr&& r); // \ref{util.smartptr.shared.mod}, modifiers void swap(shared_ptr& r) noexcept; void reset() noexcept; - template + template void reset(Y* p); - template + template void reset(Y* p, D d); - template + template void reset(Y* p, D d, A a); // \ref{util.smartptr.shared.obs}, observers @@ -9147,15 +9146,15 @@ element_type& operator[](ptrdiff_t i) const; long use_count() const noexcept; explicit operator bool() const noexcept; - template + template bool owner_before(const shared_ptr& b) const noexcept; - template + template bool owner_before(const weak_ptr& b) const noexcept; }; - template + template shared_ptr(weak_ptr) -> shared_ptr; - template + template shared_ptr(unique_ptr) -> shared_ptr; } \end{codeblock} @@ -9184,14 +9183,14 @@ reflect modifications that can introduce data races. \pnum -For the purposes of subclause \ref{util.smartptr}, +For the purposes of subclause \ref{smartptr}, a pointer type \tcode{Y*} is said to be \defnx{compatible with}{compatible with!\idxcode{shared_ptr}} a pointer type \tcode{T*} when either \tcode{Y*} is convertible to \tcode{T*} or \tcode{Y} is \tcode{U[N]} and \tcode{T} is \cv{}~\tcode{U[]}. -\rSec4[util.smartptr.shared.const]{\tcode{shared_ptr} constructors} +\rSec3[util.smartptr.shared.const]{\tcode{shared_ptr} constructors} \pnum In the constructor definitions below, @@ -9221,7 +9220,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} -template explicit shared_ptr(Y* p); +template explicit shared_ptr(Y* p); \end{itemdecl} \begin{itemdescr} @@ -9260,10 +9259,10 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} -template shared_ptr(Y* p, D d); -template shared_ptr(Y* p, D d, A a); -template shared_ptr(nullptr_t p, D d); -template shared_ptr(nullptr_t p, D d, A a); +template shared_ptr(Y* p, D d); +template shared_ptr(Y* p, D d, A a); +template shared_ptr(nullptr_t p, D d); +template shared_ptr(nullptr_t p, D d, A a); \end{itemdecl} \begin{itemdescr} @@ -9303,7 +9302,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} -template shared_ptr(const shared_ptr& r, element_type* p) noexcept; +template shared_ptr(const shared_ptr& r, element_type* p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9327,7 +9326,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} shared_ptr(const shared_ptr& r) noexcept; -template shared_ptr(const shared_ptr& r) noexcept; +template shared_ptr(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9345,7 +9344,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \begin{itemdecl} shared_ptr(shared_ptr&& r) noexcept; -template shared_ptr(shared_ptr&& r) noexcept; +template shared_ptr(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9364,7 +9363,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \indexlibrary{\idxcode{weak_ptr}}% \begin{itemdecl} -template explicit shared_ptr(const weak_ptr& r); +template explicit shared_ptr(const weak_ptr& r); \end{itemdecl} \begin{itemdescr} @@ -9383,7 +9382,7 @@ \indexlibrary{\idxcode{shared_ptr}!constructor}% \indexlibrary{\idxcode{unique_ptr}}% \begin{itemdecl} -template shared_ptr(unique_ptr&& r); +template shared_ptr(unique_ptr&& r); \end{itemdecl} \begin{itemdescr} @@ -9399,7 +9398,7 @@ If an exception is thrown, the constructor has no effect. \end{itemdescr} -\rSec4[util.smartptr.shared.dest]{\tcode{shared_ptr} destructor} +\rSec3[util.smartptr.shared.dest]{\tcode{shared_ptr} destructor} \indexlibrary{\idxcode{shared_ptr}!destructor}% \begin{itemdecl} @@ -9430,12 +9429,12 @@ \tcode{*this} will report a \tcode{use_count()} that is one less than its previous value. \end{note} -\rSec4[util.smartptr.shared.assign]{\tcode{shared_ptr} assignment} +\rSec3[util.smartptr.shared.assign]{\tcode{shared_ptr} assignment} \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} shared_ptr& operator=(const shared_ptr& r) noexcept; -template shared_ptr& operator=(const shared_ptr& r) noexcept; +template shared_ptr& operator=(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9461,7 +9460,7 @@ \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} shared_ptr& operator=(shared_ptr&& r) noexcept; -template shared_ptr& operator=(shared_ptr&& r) noexcept; +template shared_ptr& operator=(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9474,7 +9473,7 @@ \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} -template shared_ptr& operator=(unique_ptr&& r); +template shared_ptr& operator=(unique_ptr&& r); \end{itemdecl} \begin{itemdescr} @@ -9485,9 +9484,7 @@ \returns \tcode{*this}. \end{itemdescr} - - -\rSec4[util.smartptr.shared.mod]{\tcode{shared_ptr} modifiers} +\rSec3[util.smartptr.shared.mod]{\tcode{shared_ptr} modifiers} \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} @@ -9510,7 +9507,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p); +template void reset(Y* p); \end{itemdecl} \begin{itemdescr} @@ -9519,7 +9516,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p, D d); +template void reset(Y* p, D d); \end{itemdecl} \begin{itemdescr} @@ -9528,7 +9525,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p, D d, A a); +template void reset(Y* p, D d, A a); \end{itemdecl} \begin{itemdescr} @@ -9536,7 +9533,7 @@ \effects Equivalent to \tcode{shared_ptr(p, d, a).swap(*this)}. \end{itemdescr} -\rSec4[util.smartptr.shared.obs]{\tcode{shared_ptr} observers} +\rSec3[util.smartptr.shared.obs]{\tcode{shared_ptr} observers} \indexlibrarymember{get}{shared_ptr}% \begin{itemdecl} element_type* get() const noexcept; @@ -9636,8 +9633,8 @@ \indexlibrarymember{owner_before}{shared_ptr}% \begin{itemdecl} -template bool owner_before(const shared_ptr& b) const noexcept; -template bool owner_before(const weak_ptr& b) const noexcept; +template bool owner_before(const shared_ptr& b) const noexcept; +template bool owner_before(const weak_ptr& b) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9655,8 +9652,7 @@ \end{itemdescr} - -\rSec4[util.smartptr.shared.create]{\tcode{shared_ptr} creation} +\rSec3[util.smartptr.shared.create]{\tcode{shared_ptr} creation} \pnum The common requirements that apply to @@ -9666,9 +9662,9 @@ \indexlibrary{\idxcode{make_shared}}% \indexlibrary{\idxcode{allocate_shared}}% \begin{itemdecl} -template +template shared_ptr make_shared(@\placeholdernc{args}@); -template +template shared_ptr allocate_shared(const A& a, @\placeholdernc{args}@); \end{itemdecl} @@ -9773,9 +9769,9 @@ \indexlibrary{\idxcode{make_shared}}% \indexlibrary{\idxcode{allocate_shared}}% \begin{itemdecl} -template +template shared_ptr make_shared(Args&&... args); // \tcode{T} is not array -template +template shared_ptr allocate_shared(const A& a, Args&&... args); // \tcode{T} is not array \end{itemdecl} @@ -9804,9 +9800,9 @@ \indexlibrary{\idxcode{make_shared}}% \indexlibrary{\idxcode{allocate_shared}}% \begin{itemdecl} -template shared_ptr +template shared_ptr make_shared(size_t N); // \tcode{T} is \tcode{U[]} -template +template shared_ptr allocate_shared(const A& a, size_t N); // \tcode{T} is \tcode{U[]} \end{itemdecl} @@ -9834,9 +9830,9 @@ \indexlibrary{\idxcode{make_shared}}% \indexlibrary{\idxcode{allocate_shared}}% \begin{itemdecl} -template +template shared_ptr make_shared(); // \tcode{T} is \tcode{U[N]} -template +template shared_ptr allocate_shared(const A& a); // \tcode{T} is \tcode{U[N]} \end{itemdecl} @@ -9927,11 +9923,11 @@ \end{example} \end{itemdescr} -\rSec4[util.smartptr.shared.cmp]{\tcode{shared_ptr} comparison} +\rSec3[util.smartptr.shared.cmp]{\tcode{shared_ptr} comparison} \indexlibrarymember{operator==}{shared_ptr}% \begin{itemdecl} -template +template bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; \end{itemdecl} @@ -9942,7 +9938,7 @@ \indexlibrarymember{operator<}{shared_ptr}% \begin{itemdecl} -template +template bool operator<(const shared_ptr& a, const shared_ptr& b) noexcept; \end{itemdecl} @@ -9959,9 +9955,9 @@ \indexlibrarymember{operator==}{shared_ptr}% \begin{itemdecl} -template +template bool operator==(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator==(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -9972,9 +9968,9 @@ \indexlibrarymember{operator"!=}{shared_ptr}% \begin{itemdecl} -template +template bool operator!=(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator!=(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -9985,9 +9981,9 @@ \indexlibrarymember{operator<}{shared_ptr}% \begin{itemdecl} -template +template bool operator<(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator<(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -10006,9 +10002,9 @@ \indexlibrarymember{operator>}{shared_ptr}% \begin{itemdecl} -template +template bool operator>(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator>(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -10021,9 +10017,9 @@ \indexlibrarymember{operator<=}{shared_ptr}% \begin{itemdecl} -template +template bool operator<=(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator<=(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -10036,9 +10032,9 @@ \indexlibrarymember{operator>=}{shared_ptr}% \begin{itemdecl} -template +template bool operator>=(const shared_ptr& a, nullptr_t) noexcept; -template +template bool operator>=(nullptr_t, const shared_ptr& a) noexcept; \end{itemdecl} @@ -10049,11 +10045,11 @@ The second function template returns \tcode{!(nullptr < a)}. \end{itemdescr} -\rSec4[util.smartptr.shared.spec]{\tcode{shared_ptr} specialized algorithms} +\rSec3[util.smartptr.shared.spec]{\tcode{shared_ptr} specialized algorithms} \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} -template +template void swap(shared_ptr& a, shared_ptr& b) noexcept; \end{itemdecl} @@ -10061,11 +10057,11 @@ \pnum\effects Equivalent to \tcode{a.swap(b)}. \end{itemdescr} -\rSec4[util.smartptr.shared.cast]{\tcode{shared_ptr} casts} +\rSec3[util.smartptr.shared.cast]{\tcode{shared_ptr} casts} \indexlibrarymember{static_pointer_cast}{shared_ptr}% \begin{itemdecl} -template +template shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; \end{itemdecl} @@ -10091,14 +10087,16 @@ \indexlibrarymember{dynamic_pointer_cast}{shared_ptr}% \begin{itemdecl} -template +template shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \requires The expression \tcode{dynamic_cast((U*)nullptr)} -shall be well-formed and shall have well-defined behavior. +shall be well-formed. +The expression \tcode{dynamic_cast::element_type*>(r.get())} +shall be well formed and shall have well-defined behavior. \pnum \returns @@ -10118,7 +10116,7 @@ \indexlibrarymember{const_pointer_cast}{shared_ptr}% \begin{itemdecl} -template +template shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; \end{itemdecl} @@ -10143,7 +10141,7 @@ \indexlibrarymember{reinterpret_pointer_cast}{shared_ptr}% \begin{itemdecl} -template +template shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; \end{itemdecl} @@ -10165,11 +10163,11 @@ \end{note} \end{itemdescr} -\rSec4[util.smartptr.getdeleter]{\tcode{get_deleter}} +\rSec3[util.smartptr.getdeleter]{\tcode{get_deleter}} \indexlibrarymember{get_deleter}{shared_ptr}% \begin{itemdecl} -template +template D* get_deleter(const shared_ptr& p) noexcept; \end{itemdecl} @@ -10184,11 +10182,11 @@ \tcode{p} have been destroyed. \end{note} \end{itemdescr} -\rSec4[util.smartptr.shared.io]{\tcode{shared_ptr} I/O} +\rSec3[util.smartptr.shared.io]{\tcode{shared_ptr} I/O} \indexlibrarymember{operator<<}{shared_ptr}% \begin{itemdecl} -template +template basic_ostream& operator<<(basic_ostream& os, const shared_ptr& p); \end{itemdecl} @@ -10198,7 +10196,7 @@ \pnum\returns \tcode{os}. \end{itemdescr} -\rSec3[util.smartptr.weak]{Class template \tcode{weak_ptr}} +\rSec2[util.smartptr.weak]{Class template \tcode{weak_ptr}} \pnum \indexlibrary{\idxcode{weak_ptr}}% @@ -10211,7 +10209,7 @@ namespace std { template class weak_ptr { public: - using element_type = T; + using element_type = remove_extent_t; // \ref{util.smartptr.weak.const}, constructors constexpr weak_ptr() noexcept; @@ -10266,7 +10264,7 @@ containers. The template parameter \tcode{T} of \tcode{weak_ptr} may be an incomplete type. -\rSec4[util.smartptr.weak.const]{\tcode{weak_ptr} constructors} +\rSec3[util.smartptr.weak.const]{\tcode{weak_ptr} constructors} \indexlibrary{\idxcode{weak_ptr}!constructor}% \begin{itemdecl} @@ -10314,7 +10312,7 @@ \tcode{r} shall be empty. \tcode{r.use_count() == 0}. \end{itemdescr} -\rSec4[util.smartptr.weak.dest]{\tcode{weak_ptr} destructor} +\rSec3[util.smartptr.weak.dest]{\tcode{weak_ptr} destructor} \indexlibrary{\idxcode{weak_ptr}!destructor}% \begin{itemdecl} @@ -10326,7 +10324,7 @@ effect on the object its stored pointer points to. \end{itemdescr} -\rSec4[util.smartptr.weak.assign]{\tcode{weak_ptr} assignment} +\rSec3[util.smartptr.weak.assign]{\tcode{weak_ptr} assignment} \indexlibrarymember{operator=}{weak_ptr}% \begin{itemdecl} @@ -10356,7 +10354,7 @@ \pnum\returns \tcode{*this}. \end{itemdescr} -\rSec4[util.smartptr.weak.mod]{\tcode{weak_ptr} modifiers} +\rSec3[util.smartptr.weak.mod]{\tcode{weak_ptr} modifiers} \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} void swap(weak_ptr& r) noexcept; @@ -10375,7 +10373,7 @@ \pnum\effects Equivalent to \tcode{weak_ptr().swap(*this)}. \end{itemdescr} -\rSec4[util.smartptr.weak.obs]{\tcode{weak_ptr} observers} +\rSec3[util.smartptr.weak.obs]{\tcode{weak_ptr} observers} \indexlibrarymember{use_count}{weak_ptr}% \begin{itemdecl} long use_count() const noexcept; @@ -10427,7 +10425,7 @@ \end{itemdescr} -\rSec4[util.smartptr.weak.spec]{\tcode{weak_ptr} specialized algorithms} +\rSec3[util.smartptr.weak.spec]{\tcode{weak_ptr} specialized algorithms} \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} @@ -10436,10 +10434,10 @@ \end{itemdecl} \begin{itemdescr} -\pnum\effects Equivalent to \tcode{a.swap(b)}. +\pnum\effects Equivalent to \tcode{a.swap(b)}. \end{itemdescr} -\rSec3[util.smartptr.ownerless]{Class template \tcode{owner_less}} +\rSec2[util.smartptr.ownerless]{Class template \tcode{owner_less}} \pnum The class template \tcode{owner_less} allows ownership-based mixed comparisons of shared @@ -10490,7 +10488,7 @@ both empty. \end{itemize} \end{note} -\rSec3[util.smartptr.enab]{Class template \tcode{enable_shared_from_this}} +\rSec2[util.smartptr.enab]{Class template \tcode{enable_shared_from_this}} \pnum \indexlibrary{\idxcode{enable_shared_from_this}}% @@ -10580,252 +10578,551 @@ \pnum\returns \tcode{weak_this}. \end{itemdescr} -\rSec3[util.smartptr.shared.atomic]{\tcode{shared_ptr} atomic access} - -\pnum -Concurrent access to a \tcode{shared_ptr} object from multiple threads does not -introduce a data race if the access is done exclusively via the functions in -this section and the instance is passed as their first argument. +\rSec2[util.smartptr.hash]{Smart pointer hash support} -\pnum -The meaning of the arguments of type \tcode{memory_order} is explained in~\ref{atomics.order}. +\indexlibrary{\idxcode{hash}!\idxcode{unique_ptr}}% +\begin{itemdecl} +template struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Letting \tcode{UP} be \tcode{unique_ptr}, +the specialization \tcode{hash} is enabled\iref{unord.hash} +if and only if \tcode{hash} is enabled. +When enabled, for an object \tcode{p} of type \tcode{UP}, +\tcode{hash()(p)} shall evaluate to +the same value as \tcode{hash()(p.get())}. +The member functions are not guaranteed to be \tcode{noexcept}. +\end{itemdescr} -\indexlibrarymember{atomic_is_lock_free}{shared_ptr}% +\indexlibrary{\idxcode{hash}!\idxcode{shared_ptr}}% \begin{itemdecl} -template - bool atomic_is_lock_free(const shared_ptr* p); +template struct hash>; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +For an object \tcode{p} of type \tcode{shared_ptr}, +\tcode{hash>()(p)} shall evaluate to +the same value as \tcode{hash::element_type*>()(p.get())}. +\end{itemdescr}% +\indextext{smart pointers|)} + +\indextext{atomic smart pointers|(}% +\rSec2[util.smartptr.atomic]{Atomic specializations for smart pointers} \pnum -\returns \tcode{true} if atomic access to \tcode{*p} is lock-free, \tcode{false} otherwise. +The library provides partial specializations of the \tcode{atomic} template +for shared-ownership smart pointers. +The behavior of all operations is as specified in \ref{atomics.types.generic}, +unless specified otherwise. +The template parameter \tcode{T} of these partial specializations +may be an incomplete type. \pnum -\throws Nothing. +All changes to an atomic smart pointer in this subclause, and +all associated \tcode{use_count} increments, +are guaranteed to be performed atomically. +Associated \tcode{use_count} decrements +are sequenced after the atomic operation, +but are not required to be part of it. +Any associated deletion and deallocation +are sequenced after the atomic update step and +are not part of the atomic operation. +\begin{note} +If the atomic operation uses locks, +locks acquired by the implementation +will be held when any \tcode{use_count} adjustments are performed, and +will not be held when any destruction or deallocation +resulting from this is performed. +\end{note} + +\rSec3[util.smartptr.atomic.shared]{Atomic specialization for \tcode{shared_ptr}} +\indexlibrary{\idxcode{atomic>}}% +\begin{codeblock} +namespace std { + template struct atomic> { + using value_type = shared_ptr; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; + + bool is_lock_free() const noexcept; + void store(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; + shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; + operator shared_ptr() const noexcept; + + shared_ptr exchange(shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; + bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; + + bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + constexpr atomic() noexcept = default; + atomic(shared_ptr desired) noexcept; + atomic(const atomic&) = delete; + void operator=(const atomic&) = delete; + void operator=(shared_ptr desired) noexcept; + + private: + shared_ptr p; // \expos + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{atomic>}!constructor}% +\begin{itemdecl} +constexpr atomic() noexcept = default; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{p\{\}}. \end{itemdescr} -\indexlibrarymember{atomic_load}{shared_ptr}% +\indexlibrary{\idxcode{atomic>}!constructor}% \begin{itemdecl} -template - shared_ptr atomic_load(const shared_ptr* p); +atomic(shared_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\effects +Initializes the object with the value \tcode{desired}. +Initialization is not an atomic operation\iref{intro.multithread}. +\begin{note} +It is possible to have an access to +an atomic object \tcode{A} race with its construction, +for example, +by communicating the address of the just-constructed object \tcode{A} +to another thread via \tcode{memory_order::relaxed} operations +on a suitable atomic pointer variable, and +then immediately accessing \tcode{A} in the receiving thread. +This results in undefined behavior. +\end{note} +\end{itemdescr} + +\indexlibrarymember{store}{atomic>}% +\begin{itemdecl} +void store(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{atomic_load_explicit(p, memory_order_seq_cst)}. +\requires +The \tcode{order} argument shall not be +\tcode{memory_order::consume}, +\tcode{memory_order::acquire}, nor +\tcode{memory_order::acq_rel}. \pnum -\throws Nothing. +\effects +Atomically replaces the value pointed to by \tcode{this} with +the value of \tcode{desired} as if by \tcode{p.swap(desired)}. +Memory is affected according to the value of \tcode{order}. \end{itemdescr} -\indexlibrarymember{atomic_load_explicit}{shared_ptr}% +\indexlibrarymember{operator=}{atomic>}% \begin{itemdecl} -template - shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); +void operator=(shared_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\effects +Equivalent to \tcode{store(desired)}. +\end{itemdescr} + +\indexlibrarymember{load}{atomic>}% +\begin{itemdecl} +shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\requires \tcode{mo} shall not be \tcode{memory_order_release} or \tcode{memory_order_acq_rel}. +\requires +\tcode{order} shall not be +\tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. \pnum -\returns \tcode{*p}. +\effects +Memory is affected according to the value of \tcode{order}. \pnum -\throws Nothing. +\returns +Atomically returns \tcode{p}. \end{itemdescr} -\indexlibrarymember{atomic_store}{shared_ptr}% +\indexlibrarymember{operator shared_ptr}{atomic>}% \begin{itemdecl} -template - void atomic_store(shared_ptr* p, shared_ptr r); +operator shared_ptr() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\effects +Equivalent to: \tcode{return load();} +\end{itemdescr} +\indexlibrarymember{exchange}{atomic>}% +\begin{itemdecl} +shared_ptr exchange(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\effects As if by \tcode{atomic_store_explicit(p, r, memory_order_seq_cst)}. +\effects +Atomically replaces \tcode{p} with \tcode{desired} +as if by \tcode{p.swap(desired)}. +Memory is affected according to the value of \tcode{order}. +This is an atomic read-modify-write operation\iref{intro.races}. \pnum -\throws Nothing. +\returns +Atomically returns the value of \tcode{p} immediately before the effects. \end{itemdescr} -\indexlibrarymember{atomic_store_explicit}{shared_ptr}% +\indexlibrarymember{compare_exchange_weak}{atomic>}% +\indexlibrarymember{compare_exchange_strong}{atomic>}% \begin{itemdecl} -template - void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; +bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\requires +\tcode{failure} shall not be +\tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. \pnum -\requires \tcode{mo} shall not be \tcode{memory_order_acquire} or \tcode{memory_order_acq_rel}. +\effects +If \tcode{p} is equivalent to \tcode{expected}, +assigns \tcode{desired} to \tcode{p} and +has synchronization semantics corresponding to the value of \tcode{success}, +otherwise assigns \tcode{p} to \tcode{expected} and +has synchronization semantics corresponding to the value of \tcode{failure}. \pnum -\effects As if by \tcode{p->swap(r)}. +\returns +\tcode{true} if \tcode{p} was equivalent to \tcode{expected}, +\tcode{false} otherwise. \pnum -\throws Nothing. +\remarks +Two \tcode{shared_ptr} objects are equivalent if +they store the same pointer value and +either share ownership, or both are empty. +The weak form may fail spuriously. See \ref{atomics.types.operations}. + +\pnum +If the operation returns \tcode{true}, +\tcode{expected} is not accessed after the atomic update and +the operation is an atomic read-modify-write operation\iref{intro.multithread} +on the memory pointed to by \tcode{this}. +Otherwise, the operation is an atomic load operation on that memory, and +\tcode{expected} is updated with the existing value +read from the atomic object in the attempted atomic update. +The \tcode{use_count} update corresponding to the write to \tcode{expected} +is part of the atomic operation. +The write to \tcode{expected} itself +is not required to be part of the atomic operation. \end{itemdescr} -\indexlibrarymember{atomic_exchange}{shared_ptr}% +\indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -template - shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); +bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\effects +Equivalent to: +\begin{codeblock} +return compare_exchange_weak(expected, desired, order, fail_order); +\end{codeblock} +where \tcode{fail_order} is the same as \tcode{order} +except that a value of \tcode{memory_order::acq_rel} +shall be replaced by the value \tcode{memory_order::acquire} and +a value of \tcode{memory_order::release} +shall be replaced by the value \tcode{memory_order::relaxed}. +\end{itemdescr} +\indexlibrarymember{compare_exchange_strong}{atomic>}% +\begin{itemdecl} +bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\returns \tcode{atomic_exchange_explicit(p, r, memory_order_seq_cst)}. +\effects +Equivalent to: +\begin{codeblock} +return compare_exchange_strong(expected, desired, order, fail_order); +\end{codeblock} +where \tcode{fail_order} is the same as \tcode{order} +except that a value of \tcode{memory_order::acq_rel} +shall be replaced by the value \tcode{memory_order::acquire} and +a value of \tcode{memory_order::release} +shall be replaced by the value \tcode{memory_order::relaxed}. +\end{itemdescr} +\rSec3[util.smartptr.atomic.weak]{Atomic specialization for \tcode{weak_ptr}} +\indexlibrary{\idxcode{atomic>}}% +\begin{codeblock} +namespace std { + template struct atomic> { + using value_type = weak_ptr; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@; + + bool is_lock_free() const noexcept; + void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; + weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; + operator weak_ptr() const noexcept; + + weak_ptr exchange(weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; + bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; + + bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + constexpr atomic() noexcept = default; + atomic(weak_ptr desired) noexcept; + atomic(const atomic&) = delete; + void operator=(const atomic&) = delete; + void operator=(weak_ptr desired) noexcept; + + private: + weak_ptr p; // \expos + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{atomic>}!constructor}% +\begin{itemdecl} +constexpr atomic() noexcept = default; +\end{itemdecl} + +\begin{itemdescr} \pnum -\throws Nothing. +\effects +Initializes \tcode{p\{\}}. \end{itemdescr} -\indexlibrarymember{atomic_exchange_explicit}{shared_ptr}% +\indexlibrary{\idxcode{atomic>}!constructor}% \begin{itemdecl} -template - shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +atomic(weak_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null. +\effects +Initializes the object with the value \tcode{desired}. +Initialization is not an atomic operation\iref{intro.multithread}. +\begin{note} +It is possible to have an access to +an atomic object \tcode{A} race with its construction, +for example, +by communicating the address of the just-constructed object \tcode{A} +to another thread via \tcode{memory_order::relaxed} operations +on a suitable atomic pointer variable, and +then immediately accessing \tcode{A} in the receiving thread. +This results in undefined behavior. +\end{note} +\end{itemdescr} +\indexlibrarymember{store}{atomic>}% +\begin{itemdecl} +void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\effects As if by \tcode{p->swap(r)}. +\requires +The \tcode{order} argument shall not be +\tcode{memory_order::consume}, +\tcode{memory_order::acquire}, nor +\tcode{memory_order::acq_rel}. \pnum -\returns The previous value of \tcode{*p}. +\effects +Atomically replaces the value pointed to by \tcode{this} with +the value of \tcode{desired} as if by \tcode{p.swap(desired)}. +Memory is affected according to the value of \tcode{order}. +\end{itemdescr} +\indexlibrarymember{operator=}{atomic>}% +\begin{itemdecl} +void operator=(weak_ptr desired) noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\throws Nothing. +\effects +Equivalent to \tcode{store(desired)}. \end{itemdescr} -\indexlibrarymember{atomic_compare_exchange_weak}{shared_ptr}% +\indexlibrarymember{load}{atomic>}% \begin{itemdecl} -template - bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); +weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null and \tcode{v} shall not be null. +\requires +\tcode{order} shall not be +\tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. + +\pnum +\effects +Memory is affected according to the value of \tcode{order}. \pnum \returns -\begin{codeblock} -atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst) -\end{codeblock} +Atomically returns \tcode{p}. +\end{itemdescr} +\indexlibrarymember{operator weak_ptr}{atomic>}% +\begin{itemdecl} +operator weak_ptr() const noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\throws Nothing. +\effects +Equivalent to: \tcode{return load();} \end{itemdescr} -\indexlibrarymember{atomic_compare_exchange_strong}{shared_ptr}% +\indexlibrarymember{exchange}{atomic>}% \begin{itemdecl} -template - bool atomic_compare_exchange_strong(shared_ptr* p, shared_ptr* v, shared_ptr w); +weak_ptr exchange(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\effects +Atomically replaces \tcode{p} with \tcode{desired} +as if by \tcode{p.swap(desired)}. +Memory is affected according to the value of \tcode{order}. +This is an atomic read-modify-write operation\iref{intro.races}. + \pnum \returns -\begin{codeblock} -atomic_compare_exchange_strong_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst) -\end{codeblock} +Atomically returns the value of \tcode{p} immediately before the effects. \end{itemdescr} -\indexlibrarymember{atomic_compare_exchange_weak_explicit}{shared_ptr}% -\indexlibrarymember{atomic_compare_exchange_strong_explicit}{shared_ptr}% +\indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -template - bool atomic_compare_exchange_weak_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); -template - bool atomic_compare_exchange_strong_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); +bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; +bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{p} shall not be null and \tcode{v} shall not be null. -The \tcode{failure} argument shall not be \tcode{memory_order_release} nor -\tcode{memory_order_acq_rel}. +\requires +\tcode{failure} shall not be +\tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. \pnum -\effects If \tcode{*p} is equivalent to \tcode{*v}, assigns \tcode{w} to -\tcode{*p} and has synchronization semantics corresponding to the value of -\tcode{success}, otherwise assigns \tcode{*p} to \tcode{*v} and has -synchronization semantics corresponding to the value of \tcode{failure}. +\effects +If \tcode{p} is equivalent to \tcode{expected}, +assigns \tcode{desired} to \tcode{p} and +has synchronization semantics corresponding to the value of \tcode{success}, +otherwise assigns \tcode{p} to \tcode{expected} and +has synchronization semantics corresponding to the value of \tcode{failure}. \pnum -\returns \tcode{true} if \tcode{*p} was equivalent to \tcode{*v}, \tcode{false} otherwise. +\returns +\tcode{true} if \tcode{p} was equivalent to \tcode{expected}, +\tcode{false} otherwise. \pnum -\throws Nothing. +\remarks +Two \tcode{weak_ptr} objects are equivalent if +they store the same pointer value and +either share ownership, or both are empty. +The weak form may fail spuriously. See \ref{atomics.types.operations}. \pnum -\remarks Two \tcode{shared_ptr} objects are equivalent if they store the same -pointer value and share ownership. -The weak form may fail spuriously. See~\ref{atomics.types.operations}. +If the operation returns \tcode{true}, +\tcode{expected} is not accessed after the atomic update and +the operation is an atomic read-modify-write operation\iref{intro.multithread} +on the memory pointed to by \tcode{this}. +Otherwise, the operation is an atomic load operation on that memory, and +\tcode{expected} is updated with the existing value +read from the atomic object in the attempted atomic update. +The \tcode{use_count} update corresponding to the write to \tcode{expected} +is part of the atomic operation. +The write to \tcode{expected} itself +is not required to be part of the atomic operation. \end{itemdescr} -\rSec3[util.smartptr.hash]{Smart pointer hash support} - -\indexlibrary{\idxcode{hash}!\idxcode{unique_ptr}}% +\indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -template struct hash>; +bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -Letting \tcode{UP} be \tcode{unique_ptr}, -the specialization \tcode{hash} is enabled\iref{unord.hash} -if and only if \tcode{hash} is enabled. -When enabled, for an object \tcode{p} of type \tcode{UP}, -\tcode{hash()(p)} shall evaluate to -the same value as \tcode{hash()(p.get())}. -The member functions are not guaranteed to be \tcode{noexcept}. +\effects +Equivalent to: +\begin{codeblock} +return compare_exchange_weak(expected, desired, order, fail_order); +\end{codeblock} +where \tcode{fail_order} is the same as \tcode{order} +except that a value of \tcode{memory_order::acq_rel} +shall be replaced by the value \tcode{memory_order::acquire} and +a value of \tcode{memory_order::release} +shall be replaced by the value \tcode{memory_order::relaxed}. \end{itemdescr} -\indexlibrary{\idxcode{hash}!\idxcode{shared_ptr}}% +\indexlibrarymember{compare_exchange_strong}{atomic>}% \begin{itemdecl} -template struct hash>; +bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -For an object \tcode{p} of type \tcode{shared_ptr}, -\tcode{hash>()(p)} shall evaluate to -the same value as \tcode{hash::element_type*>()(p.get())}. -\end{itemdescr}% -\indextext{smart pointers|)} +\effects +Equivalent to: +\begin{codeblock} +return compare_exchange_strong(expected, desired, order, fail_order); +\end{codeblock} +where \tcode{fail_order} is the same as \tcode{order} +except that a value of \tcode{memory_order::acq_rel} +shall be replaced by the value \tcode{memory_order::acquire} and +a value of \tcode{memory_order::release} +shall be replaced by the value \tcode{memory_order::relaxed}. +\end{itemdescr} +\indextext{atomic smart pointers|)} \rSec1[mem.res]{Memory resources} \rSec2[mem.res.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{memory_resource}}% -\indexlibrary{\idxhdr{memory_resource}}% +\indexhdr{memory_resource}% \begin{codeblock} namespace std::pmr { // \ref{mem.res.class}, class \tcode{memory_resource} @@ -10835,12 +11132,12 @@ bool operator!=(const memory_resource& a, const memory_resource& b) noexcept; // \ref{mem.poly.allocator.class}, class template \tcode{polymorphic_allocator} - template class polymorphic_allocator; + template class polymorphic_allocator; - template + template bool operator==(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept; - template + template bool operator!=(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept; @@ -10872,7 +11169,7 @@ public: virtual ~memory_resource(); - void* allocate(size_t bytes, size_t alignment = max_align); + [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align); void deallocate(void* p, size_t bytes, size_t alignment = max_align); bool is_equal(const memory_resource& other) const noexcept; @@ -10902,7 +11199,7 @@ \indexlibrarymember{allocate}{memory_resource}% \begin{itemdecl} -void* allocate(size_t bytes, size_t alignment = max_align); +[[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align); \end{itemdecl} \begin{itemdescr} @@ -10919,7 +11216,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{do_deallocate(p, bytes, alignment);} +Equivalent to \tcode{do_deallocate(p, bytes, alignment)}. \end{itemdescr} \indexlibrarymember{is_equal}{memory_resource}% @@ -10948,7 +11245,7 @@ \pnum \returns -A derived class shall implement this function to return a pointer to allocated storage\iref{basic.stc.dynamic.deallocation} with a size of at least \tcode{bytes}. +A derived class shall implement this function to return a pointer to allocated storage\iref{basic.stc.dynamic.allocation} with a size of at least \tcode{bytes}. The returned storage is aligned to the specified alignment, if such alignment is supported\iref{basic.align}; otherwise it is aligned to \tcode{max_align}. @@ -11031,9 +11328,10 @@ even though they use the same static allocator type. \indexlibrary{\idxcode{polymorphic_allocator}}% +\indexlibrarymember{value_type}{polymorphic_allocator}% \begin{codeblock} namespace std::pmr { - template + template class polymorphic_allocator { memory_resource* memory_rsrc; // \expos @@ -11046,31 +11344,31 @@ polymorphic_allocator(const polymorphic_allocator& other) = default; - template + template polymorphic_allocator(const polymorphic_allocator& other) noexcept; polymorphic_allocator& operator=(const polymorphic_allocator& rhs) = delete; // \ref{mem.poly.allocator.mem}, member functions - Tp* allocate(size_t n); + [[nodiscard]] Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); - template + template void construct(T* p, Args&&... args); - template - void construct(pair* p, piecewise_construct_t, + 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 + 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); polymorphic_allocator select_on_container_copy_construction() const; @@ -11119,7 +11417,7 @@ \indexlibrary{\idxcode{polymorphic_allocator}!constructor}% \begin{itemdecl} -template +template polymorphic_allocator(const polymorphic_allocator& other) noexcept; \end{itemdecl} @@ -11134,13 +11432,13 @@ \indexlibrarymember{allocate}{polymorphic_allocator}% \begin{itemdecl} -Tp* allocate(size_t n); +[[nodiscard]] Tp* allocate(size_t n); \end{itemdecl} \begin{itemdescr} \pnum -\returns -Equivalent to +\effects +Equivalent to: \begin{codeblock} return static_cast(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp))); \end{codeblock} @@ -11169,7 +11467,7 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template +template void construct(T* p, Args&&... args); \end{itemdecl} @@ -11197,8 +11495,8 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template - void construct(pair* p, piecewise_construct_t, tuple x, tuple y); +template + void construct(pair* p, piecewise_construct_t, tuple x, tuple y); \end{itemdecl} \begin{itemdescr} @@ -11283,8 +11581,8 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template - void construct(pair* p); +template + void construct(pair* p); \end{itemdecl} \begin{itemdescr} @@ -11298,8 +11596,8 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template - void construct(pair* p, U&& x, V&& y); +template + void construct(pair* p, U&& x, V&& y); \end{itemdecl} \begin{itemdescr} @@ -11315,8 +11613,8 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template - void construct(pair* p, const pair& pr); +template + void construct(pair* p, const pair& pr); \end{itemdecl} \begin{itemdescr} @@ -11332,8 +11630,8 @@ \indexlibrarymember{construct}{polymorphic_allocator}% \begin{itemdecl} -template - void construct(pair* p, pair&& pr); +template + void construct(pair* p, pair&& pr); \end{itemdecl} \begin{itemdescr} @@ -11349,7 +11647,7 @@ \indexlibrarymember{destroy}{polymorphic_allocator}% \begin{itemdecl} -template +template void destroy(T* p); \end{itemdecl} @@ -11390,7 +11688,7 @@ \indexlibrarymember{operator==}{polymorphic_allocator}% \begin{itemdecl} -template +template bool operator==(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept; \end{itemdecl} @@ -11403,7 +11701,7 @@ \indexlibrarymember{operator"!=}{polymorphic_allocator}% \begin{itemdecl} -template +template bool operator!=(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept; \end{itemdecl} @@ -11571,8 +11869,8 @@ pool_options options() const; protected: - void *do_allocate(size_t bytes, size_t alignment) override; - void do_deallocate(void *p, size_t bytes, size_t alignment) override; + void* do_allocate(size_t bytes, size_t alignment) override; + void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; }; @@ -11594,7 +11892,7 @@ unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete; void release(); - memory_resource *upstream_resource() const; + memory_resource* upstream_resource() const; pool_options options() const; protected: @@ -11754,7 +12052,7 @@ \begin{itemdescr} \pnum \returns -A pointer to allocated storage\iref{basic.stc.dynamic.deallocation} +A pointer to allocated storage\iref{basic.stc.dynamic.allocation} with a size of at least \tcode{bytes}. The size and alignment of the allocated memory shall meet the requirements for a class derived from \tcode{memory_resource}\iref{mem.res}. @@ -11849,20 +12147,20 @@ \begin{codeblock} namespace std::pmr { class monotonic_buffer_resource : public memory_resource { - memory_resource *upstream_rsrc; // \expos - void *current_buffer; // \expos + memory_resource* upstream_rsrc; // \expos + void* current_buffer; // \expos size_t next_buffer_size; // \expos public: - explicit monotonic_buffer_resource(memory_resource *upstream); - monotonic_buffer_resource(size_t initial_size, memory_resource *upstream); - monotonic_buffer_resource(void *buffer, size_t buffer_size, memory_resource *upstream); + explicit monotonic_buffer_resource(memory_resource* upstream); + monotonic_buffer_resource(size_t initial_size, memory_resource* upstream); + monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream); monotonic_buffer_resource() : monotonic_buffer_resource(get_default_resource()) {} explicit monotonic_buffer_resource(size_t initial_size) : monotonic_buffer_resource(initial_size, get_default_resource()) {} - monotonic_buffer_resource(void *buffer, size_t buffer_size) + monotonic_buffer_resource(void* buffer, size_t buffer_size) : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; @@ -11978,7 +12276,7 @@ \begin{itemdescr} \pnum \returns -A pointer to allocated storage\iref{basic.stc.dynamic.deallocation} +A pointer to allocated storage\iref{basic.stc.dynamic.allocation} with a size of at least \tcode{bytes}. The size and alignment of the allocated memory shall meet the requirements for a class derived from \tcode{memory_resource}\iref{mem.res}. @@ -12035,18 +12333,18 @@ \rSec2[allocator.adaptor.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{scoped_allocator}}% -\indexlibrary{\idxhdr{scoped_allocator}}% +\indexhdr{scoped_allocator}% \begin{codeblock} namespace std { - // scoped allocator adaptor - template + // class template \tcode{scoped allocator adaptor} + template class scoped_allocator_adaptor; - template + // \ref{scoped.adaptor.operators}, scoped allocator operators + template bool operator==(const scoped_allocator_adaptor& a, const scoped_allocator_adaptor& b) noexcept; - template + template bool operator!=(const scoped_allocator_adaptor& a, const scoped_allocator_adaptor& b) noexcept; } @@ -12072,9 +12370,17 @@ expressions. \end{note} \indexlibrary{\idxcode{scoped_allocator_adaptor}}% +\indexlibrarymember{outer_allocator_type}{scoped_allocator_adaptor}% +\indexlibrarymember{value_type}{scoped_allocator_adaptor}% +\indexlibrarymember{size_type}{scoped_allocator_adaptor}% +\indexlibrarymember{difference_type}{scoped_allocator_adaptor}% +\indexlibrarymember{pointer}{scoped_allocator_adaptor}% +\indexlibrarymember{const_pointer}{scoped_allocator_adaptor}% +\indexlibrarymember{void_pointer}{scoped_allocator_adaptor}% +\indexlibrarymember{const_void_pointer}{scoped_allocator_adaptor}% \begin{codeblock} namespace std { - template + template class scoped_allocator_adaptor : public OuterAlloc { private: using OuterTraits = allocator_traits; // \expos @@ -12097,24 +12403,24 @@ using propagate_on_container_swap = @\seebelow@; using is_always_equal = @\seebelow@; - template + template struct rebind { using other = scoped_allocator_adaptor< OuterTraits::template rebind_alloc, InnerAllocs...>; }; scoped_allocator_adaptor(); - template + template scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept; scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; - template + template scoped_allocator_adaptor( const scoped_allocator_adaptor& other) noexcept; - template + template scoped_allocator_adaptor( scoped_allocator_adaptor&& other) noexcept; @@ -12128,26 +12434,26 @@ outer_allocator_type& outer_allocator() noexcept; const outer_allocator_type& outer_allocator() const noexcept; - pointer allocate(size_type n); - pointer allocate(size_type n, const_void_pointer hint); + [[nodiscard]] pointer allocate(size_type n); + [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint); void deallocate(pointer p, size_type n); size_type max_size() const; - template + template void construct(T* p, Args&&... args); - template + template void construct(pair* p, piecewise_construct_t, tuple x, tuple y); - template + template void construct(pair* p); - template + template void construct(pair* p, U&& x, V&& y); - template + template void construct(pair* p, const pair& x); - template + template void construct(pair* p, pair&& x); - template + template void destroy(T* p); scoped_allocator_adaptor select_on_container_copy_construction() const; @@ -12156,13 +12462,6 @@ template scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) -> scoped_allocator_adaptor; - - template - bool operator==(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) noexcept; - template - bool operator!=(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) noexcept; } \end{codeblock} @@ -12246,7 +12545,7 @@ \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% \begin{itemdecl} -template +template scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept; \end{itemdecl} @@ -12286,7 +12585,7 @@ \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% \begin{itemdecl} -template +template scoped_allocator_adaptor( const scoped_allocator_adaptor& other) noexcept; \end{itemdecl} @@ -12303,7 +12602,7 @@ \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% \begin{itemdecl} -template +template scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; \end{itemdecl} @@ -12367,7 +12666,7 @@ \indexlibrarymember{allocate}{scoped_allocator_adaptor}% \begin{itemdecl} -pointer allocate(size_type n); +[[nodiscard]] pointer allocate(size_type n); \end{itemdecl} \begin{itemdescr} @@ -12377,7 +12676,7 @@ \indexlibrarymember{allocate}{scoped_allocator_adaptor}% \begin{itemdecl} -pointer allocate(size_type n, const_void_pointer hint); +[[nodiscard]] pointer allocate(size_type n, const_void_pointer hint); \end{itemdecl} \begin{itemdescr} @@ -12408,7 +12707,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(T* p, Args&&... args); \end{itemdecl} @@ -12449,7 +12748,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(pair* p, piecewise_construct_t, tuple x, tuple y); \end{itemdecl} @@ -12522,7 +12821,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(pair* p); \end{itemdecl} @@ -12536,7 +12835,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(pair* p, U&& x, V&& y); \end{itemdecl} @@ -12552,7 +12851,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(pair* p, const pair& x); \end{itemdecl} @@ -12568,7 +12867,7 @@ \indexlibrarymember{construct}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void construct(pair* p, pair&& x); \end{itemdecl} @@ -12584,7 +12883,7 @@ \indexlibrarymember{destroy}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template void destroy(T* p); \end{itemdecl} @@ -12610,7 +12909,7 @@ \indexlibrarymember{operator==}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template bool operator==(const scoped_allocator_adaptor& a, const scoped_allocator_adaptor& b) noexcept; \end{itemdecl} @@ -12629,7 +12928,7 @@ \indexlibrarymember{operator"!=}{scoped_allocator_adaptor}% \begin{itemdecl} -template +template bool operator!=(const scoped_allocator_adaptor& a, const scoped_allocator_adaptor& b) noexcept; \end{itemdecl} @@ -12656,74 +12955,73 @@ \rSec2[functional.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{functional}}% -\indexlibrary{\idxhdr{functional}}% +\indexhdr{functional}% \begin{codeblock} namespace std { // \ref{func.invoke}, invoke - template + template invoke_result_t invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v); // \ref{refwrap}, \tcode{reference_wrapper} - template class reference_wrapper; + template class reference_wrapper; - template reference_wrapper ref(T&) noexcept; - template reference_wrapper cref(const T&) noexcept; - template void ref(const T&&) = delete; - template void cref(const T&&) = delete; + template reference_wrapper ref(T&) noexcept; + template reference_wrapper cref(const T&) noexcept; + template void ref(const T&&) = delete; + template void cref(const T&&) = delete; - template reference_wrapper ref(reference_wrapper) noexcept; - template reference_wrapper cref(reference_wrapper) noexcept; + template reference_wrapper ref(reference_wrapper) noexcept; + template reference_wrapper cref(reference_wrapper) noexcept; // \ref{arithmetic.operations}, arithmetic operations - template struct plus; - template struct minus; - template struct multiplies; - template struct divides; - template struct modulus; - template struct negate; - template <> struct plus; - template <> struct minus; - template <> struct multiplies; - template <> struct divides; - template <> struct modulus; - template <> struct negate; + template struct plus; + template struct minus; + template struct multiplies; + template struct divides; + template struct modulus; + template struct negate; + template<> struct plus; + template<> struct minus; + template<> struct multiplies; + template<> struct divides; + template<> struct modulus; + template<> struct negate; // \ref{comparisons}, comparisons - template struct equal_to; - template struct not_equal_to; - template struct greater; - template struct less; - template struct greater_equal; - template 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; + template struct equal_to; + template struct not_equal_to; + template struct greater; + template struct less; + template struct greater_equal; + template 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; // \ref{logical.operations}, logical operations - template struct logical_and; - template struct logical_or; - template struct logical_not; - template <> struct logical_and; - template <> struct logical_or; - template <> struct logical_not; + template struct logical_and; + template struct logical_or; + template struct logical_not; + template<> struct logical_and; + template<> struct logical_or; + template<> struct logical_not; // \ref{bitwise.operations}, bitwise operations - template struct bit_and; - template struct bit_or; - template struct bit_xor; - template struct bit_not; - template <> struct bit_and; - template <> struct bit_or; - template <> struct bit_xor; - template <> struct bit_not; + template struct bit_and; + template struct bit_or; + template struct bit_xor; + template struct bit_not; + template<> struct bit_and; + template<> struct bit_or; + template<> struct bit_xor; + template<> struct bit_not; // \ref{func.not_fn}, function template \tcode{not_fn} - template @\unspec@ not_fn(F&& f); + template @\unspec@ not_fn(F&& f); // \ref{func.bind}, bind template struct is_bind_expression; @@ -12781,20 +13079,20 @@ class boyer_moore_horspool_searcher; // \ref{unord.hash}, hash function primary template - template + template struct hash; // \ref{func.bind}, function object binders - template + template inline constexpr bool is_bind_expression_v = is_bind_expression::value; - template + template inline constexpr int is_placeholder_v = is_placeholder::value; } \end{codeblock} \pnum \begin{example} -If a \Cpp program wants to have a by-element addition of two vectors \tcode{a} +If a \Cpp{} program wants to have a by-element addition of two vectors \tcode{a} and \tcode{b} containing \tcode{double} and put the result into \tcode{a}, it can do: @@ -12847,11 +13145,11 @@ \begin{itemize} \item \tcode{(t$_1$.*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} -and \tcode{is_base_of_v>} is \tcode{true}; +and \tcode{is_base_of_v>} is \tcode{true}; \item \tcode{(t$_1$.get().*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} -and \tcode{decay_t} is a specialization of \tcode{reference_wrapper}; +and \tcode{remove_cvref_t} is a specialization of \tcode{reference_wrapper}; \item \tcode{((*t$_1$).*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} @@ -12859,11 +13157,11 @@ \item \tcode{t$_1$.*f} when \tcode{N == 1} and \tcode{f} is a pointer to data member of a class \tcode{T} -and \tcode{is_base_of_v>} is \tcode{true}; +and \tcode{is_base_of_v>} is \tcode{true}; \item \tcode{t$_1$.get().*f} when \tcode{N == 1} and \tcode{f} is a pointer to data member of a class \tcode{T} -and \tcode{decay_t} is a specialization of \tcode{reference_wrapper}; +and \tcode{remove_cvref_t} is a specialization of \tcode{reference_wrapper}; \item \tcode{(*t$_1$).*f} when \tcode{N == 1} and \tcode{f} is a pointer to data member of a class \tcode{T} @@ -12893,8 +13191,8 @@ and lvalue arguments are delivered as lvalue references. A \defn{simple call wrapper} is a forwarding call wrapper that is \tcode{CopyConstructible} and \tcode{CopyAssignable} and -whose copy constructor, move constructor, and assignment operator -do not throw exceptions. +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 @@ -12910,7 +13208,7 @@ \indexlibrary{\idxcode{invoke}}% \indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% \begin{itemdecl} -template +template invoke_result_t invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v); \end{itemdecl} @@ -12927,14 +13225,14 @@ \indextext{function object!\idxcode{reference_wrapper}}% \begin{codeblock} namespace std { - template class reference_wrapper { + template class reference_wrapper { public: // types using type = T; // construct/copy/destroy - reference_wrapper(T&) noexcept; - reference_wrapper(T&&) = delete; // do not bind to temporary objects + template + reference_wrapper(U&&) noexcept(@\seebelow@); reference_wrapper(const reference_wrapper& x) noexcept; // assignment @@ -12945,12 +13243,11 @@ T& get() const noexcept; // invocation - template + template invoke_result_t operator()(ArgTypes&&...) const; }; - template - reference_wrapper(reference_wrapper) -> reference_wrapper; + reference_wrapper(T&) -> reference_wrapper; } \end{codeblock} @@ -12965,13 +13262,28 @@ \indexlibrary{\idxcode{reference_wrapper}!constructor}% \begin{itemdecl} -reference_wrapper(T& t) noexcept; +template + reference_wrapper(U&& u) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{reference_wrapper} object that stores a -reference to \tcode{t}. +\remarks Let \tcode{\placeholdernc{FUN}} denote the exposition-only functions +\begin{codeblock} +void @\placeholdernc{FUN}@(T&) noexcept; +void @\placeholdernc{FUN}@(T&&) = delete; +\end{codeblock} +This constructor shall not participate in overload resolution unless +the expression \tcode{\placeholdernc{FUN}(declval())} is well-formed and +\tcode{is_same_v, reference_wrapper>} is \tcode{false}. +The expression inside \tcode{noexcept} +is equivalent to \tcode{noexcept(\placeholdernc{FUN}(declval()))}. + +\pnum +\effects Creates a variable \tcode{r} +as if by \tcode{T\& r = std::forward(u)}, +then constructs a \tcode{reference_wrapper} object +that stores a reference to \tcode{r}. \end{itemdescr} \indexlibrary{\idxcode{reference_wrapper}!constructor}% @@ -13020,7 +13332,7 @@ \indexlibrarymember{operator()}{reference_wrapper}% \begin{itemdecl} -template +template invoke_result_t operator()(ArgTypes&&... args) const; \end{itemdecl} @@ -13034,7 +13346,7 @@ \indexlibrarymember{ref}{reference_wrapper}% \begin{itemdecl} -template reference_wrapper ref(T& t) noexcept; +template reference_wrapper ref(T& t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -13043,7 +13355,7 @@ \indexlibrarymember{ref}{reference_wrapper}% \begin{itemdecl} -template reference_wrapper ref(reference_wrapper t) noexcept; +template reference_wrapper ref(reference_wrapper t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -13052,7 +13364,7 @@ \indexlibrarymember{cref}{reference_wrapper}% \begin{itemdecl} -template reference_wrapper cref(const T& t) noexcept; +template reference_wrapper cref(const T& t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -13061,7 +13373,7 @@ \indexlibrarymember{cref}{reference_wrapper}% \begin{itemdecl} -template reference_wrapper cref(reference_wrapper t) noexcept; +template reference_wrapper cref(reference_wrapper t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -13078,7 +13390,7 @@ \indexlibrary{\idxcode{plus}}% \begin{itemdecl} -template struct plus { +template struct plus { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13094,8 +13406,8 @@ \indexlibrary{\idxcode{plus<>}}% \begin{itemdecl} -template <> struct plus { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct plus { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) + std::forward(u)); using is_transparent = @\unspec@; @@ -13104,7 +13416,7 @@ \indexlibrarymember{operator()}{plus<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) + std::forward(u)); \end{itemdecl} @@ -13116,7 +13428,7 @@ \indexlibrary{\idxcode{minus}}% \begin{itemdecl} -template struct minus { +template struct minus { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13132,8 +13444,8 @@ \indexlibrary{\idxcode{minus<>}}% \begin{itemdecl} -template <> struct minus { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct minus { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) - std::forward(u)); using is_transparent = @\unspec@; @@ -13142,7 +13454,7 @@ \indexlibrarymember{operator()}{minus<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) - std::forward(u)); \end{itemdecl} @@ -13154,7 +13466,7 @@ \indexlibrary{\idxcode{multiplies}}% \begin{itemdecl} -template struct multiplies { +template struct multiplies { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13170,8 +13482,8 @@ \indexlibrary{\idxcode{multiplies<>}}% \begin{itemdecl} -template <> struct multiplies { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct multiplies { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) * std::forward(u)); using is_transparent = @\unspec@; @@ -13180,7 +13492,7 @@ \indexlibrarymember{operator()}{multiplies<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) * std::forward(u)); \end{itemdecl} @@ -13192,7 +13504,7 @@ \indexlibrary{\idxcode{divides}}% \begin{itemdecl} -template struct divides { +template struct divides { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13208,8 +13520,8 @@ \indexlibrary{\idxcode{divides<>}}% \begin{itemdecl} -template <> struct divides { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct divides { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) / std::forward(u)); using is_transparent = @\unspec@; @@ -13218,7 +13530,7 @@ \indexlibrarymember{operator()}{divides<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) / std::forward(u)); \end{itemdecl} @@ -13230,7 +13542,7 @@ \indexlibrary{\idxcode{modulus}}% \begin{itemdecl} -template struct modulus { +template struct modulus { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13246,8 +13558,8 @@ \indexlibrary{\idxcode{modulus<>}}% \begin{itemdecl} -template <> struct modulus { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct modulus { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) % std::forward(u)); using is_transparent = @\unspec@; @@ -13256,7 +13568,7 @@ \indexlibrarymember{operator()}{modulus<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) % std::forward(u)); \end{itemdecl} @@ -13268,7 +13580,7 @@ \indexlibrary{\idxcode{negate}}% \begin{itemdecl} -template struct negate { +template struct negate { constexpr T operator()(const T& x) const; }; \end{itemdecl} @@ -13284,8 +13596,8 @@ \indexlibrary{\idxcode{negate<>}}% \begin{itemdecl} -template <> struct negate { - template constexpr auto operator()(T&& t) const +template<> struct negate { + template constexpr auto operator()(T&& t) const -> decltype(-std::forward(t)); using is_transparent = @\unspec@; @@ -13294,7 +13606,7 @@ \indexlibrarymember{operator()}{negate<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t) const +template constexpr auto operator()(T&& t) const -> decltype(-std::forward(t)); \end{itemdecl} @@ -13330,7 +13642,7 @@ \indexlibrary{\idxcode{equal_to}}% \begin{itemdecl} -template struct equal_to { +template struct equal_to { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13346,8 +13658,8 @@ \indexlibrary{\idxcode{equal_to<>}}% \begin{itemdecl} -template <> struct equal_to { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct equal_to { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) == std::forward(u)); using is_transparent = @\unspec@; @@ -13356,7 +13668,7 @@ \indexlibrarymember{operator()}{equal_to<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) == std::forward(u)); \end{itemdecl} @@ -13368,7 +13680,7 @@ \indexlibrary{\idxcode{not_equal_to}}% \begin{itemdecl} -template struct not_equal_to { +template struct not_equal_to { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13384,8 +13696,8 @@ \indexlibrary{\idxcode{not_equal_to<>}}% \begin{itemdecl} -template <> struct not_equal_to { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct not_equal_to { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) != std::forward(u)); using is_transparent = @\unspec@; @@ -13394,7 +13706,7 @@ \indexlibrarymember{operator()}{not_equal_to<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) != std::forward(u)); \end{itemdecl} @@ -13406,7 +13718,7 @@ \indexlibrary{\idxcode{greater}}% \begin{itemdecl} -template struct greater { +template struct greater { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13422,8 +13734,8 @@ \indexlibrary{\idxcode{greater<>}}% \begin{itemdecl} -template <> struct greater { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct greater { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) > std::forward(u)); using is_transparent = @\unspec@; @@ -13432,7 +13744,7 @@ \indexlibrarymember{operator()}{greater<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) > std::forward(u)); \end{itemdecl} @@ -13444,7 +13756,7 @@ \indexlibrary{\idxcode{less}}% \begin{itemdecl} -template struct less { +template struct less { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13460,8 +13772,8 @@ \indexlibrary{\idxcode{less<>}}% \begin{itemdecl} -template <> struct less { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct less { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) < std::forward(u)); using is_transparent = @\unspec@; @@ -13470,7 +13782,7 @@ \indexlibrarymember{operator()}{less<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) < std::forward(u)); \end{itemdecl} @@ -13482,7 +13794,7 @@ \indexlibrary{\idxcode{greater_equal}}% \begin{itemdecl} -template struct greater_equal { +template struct greater_equal { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13498,8 +13810,8 @@ \indexlibrary{\idxcode{greater_equal<>}}% \begin{itemdecl} -template <> struct greater_equal { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct greater_equal { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) >= std::forward(u)); using is_transparent = @\unspec@; @@ -13508,7 +13820,7 @@ \indexlibrarymember{operator()}{greater_equal<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) >= std::forward(u)); \end{itemdecl} @@ -13520,7 +13832,7 @@ \indexlibrary{\idxcode{less_equal}}% \begin{itemdecl} -template struct less_equal { +template struct less_equal { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13536,8 +13848,8 @@ \indexlibrary{\idxcode{less_equal<>}}% \begin{itemdecl} -template <> struct less_equal { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct less_equal { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) <= std::forward(u)); using is_transparent = @\unspec@; @@ -13546,7 +13858,7 @@ \indexlibrarymember{operator()}{less_equal<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) <= std::forward(u)); \end{itemdecl} @@ -13565,7 +13877,7 @@ \indexlibrary{\idxcode{logical_and}}% \begin{itemdecl} -template struct logical_and { +template struct logical_and { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13581,8 +13893,8 @@ \indexlibrary{\idxcode{logical_and<>}}% \begin{itemdecl} -template <> struct logical_and { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct logical_and { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) && std::forward(u)); using is_transparent = @\unspec@; @@ -13591,7 +13903,7 @@ \indexlibrarymember{operator()}{logical_and<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) && std::forward(u)); \end{itemdecl} @@ -13603,7 +13915,7 @@ \indexlibrary{\idxcode{logical_or}}% \begin{itemdecl} -template struct logical_or { +template struct logical_or { constexpr bool operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13619,8 +13931,8 @@ \indexlibrary{\idxcode{logical_or<>}}% \begin{itemdecl} -template <> struct logical_or { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct logical_or { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) || std::forward(u)); using is_transparent = @\unspec@; @@ -13629,7 +13941,7 @@ \indexlibrarymember{operator()}{logical_or<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) || std::forward(u)); \end{itemdecl} @@ -13641,7 +13953,7 @@ \indexlibrary{\idxcode{logical_not}}% \begin{itemdecl} -template struct logical_not { +template struct logical_not { constexpr bool operator()(const T& x) const; }; \end{itemdecl} @@ -13657,8 +13969,8 @@ \indexlibrary{\idxcode{logical_not<>}}% \begin{itemdecl} -template <> struct logical_not { - template constexpr auto operator()(T&& t) const +template<> struct logical_not { + template constexpr auto operator()(T&& t) const -> decltype(!std::forward(t)); using is_transparent = @\unspec@; @@ -13667,7 +13979,7 @@ \indexlibrarymember{operator()}{logical_not<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t) const +template constexpr auto operator()(T&& t) const -> decltype(!std::forward(t)); \end{itemdecl} @@ -13687,7 +13999,7 @@ \indexlibrary{\idxcode{bit_and}}% \begin{itemdecl} -template struct bit_and { +template struct bit_and { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13703,8 +14015,8 @@ \indexlibrary{\idxcode{bit_and<>}}% \begin{itemdecl} -template <> struct bit_and { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct bit_and { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) & std::forward(u)); using is_transparent = @\unspec@; @@ -13713,7 +14025,7 @@ \indexlibrarymember{operator()}{bit_and<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) & std::forward(u)); \end{itemdecl} @@ -13725,7 +14037,7 @@ \indexlibrary{\idxcode{bit_or}}% \begin{itemdecl} -template struct bit_or { +template struct bit_or { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13741,8 +14053,8 @@ \indexlibrary{\idxcode{bit_or<>}}% \begin{itemdecl} -template <> struct bit_or { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct bit_or { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) | std::forward(u)); using is_transparent = @\unspec@; @@ -13751,7 +14063,7 @@ \indexlibrarymember{operator()}{bit_or<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) | std::forward(u)); \end{itemdecl} @@ -13763,7 +14075,7 @@ \indexlibrary{\idxcode{bit_xor}}% \begin{itemdecl} -template struct bit_xor { +template struct bit_xor { constexpr T operator()(const T& x, const T& y) const; }; \end{itemdecl} @@ -13779,8 +14091,8 @@ \indexlibrary{\idxcode{bit_xor<>}}% \begin{itemdecl} -template <> struct bit_xor { - template constexpr auto operator()(T&& t, U&& u) const +template<> struct bit_xor { + template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) ^ std::forward(u)); using is_transparent = @\unspec@; @@ -13789,7 +14101,7 @@ \indexlibrarymember{operator()}{bit_xor<>}% \begin{itemdecl} -template constexpr auto operator()(T&& t, U&& u) const +template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) ^ std::forward(u)); \end{itemdecl} @@ -13800,7 +14112,7 @@ \rSec3[bitwise.operations.not]{Class template \tcode{bit_not}} \begin{itemdecl} -template struct bit_not { +template struct bit_not { constexpr T operator()(const T& x) const; }; \end{itemdecl} @@ -13816,8 +14128,8 @@ \indexlibrary{\idxcode{bit_not<>}}% \begin{itemdecl} -template <> struct bit_not { - template constexpr auto operator()(T&& t) const +template<> struct bit_not { + template constexpr auto operator()(T&& t) const -> decltype(~std::forward(t)); using is_transparent = @\unspec@; @@ -13826,7 +14138,7 @@ \indexlibrarymember{operator()}{bit_not<>}% \begin{itemdecl} -template constexpr auto operator()(T&&) const +template constexpr auto operator()(T&&) const -> decltype(~std::forward(t)); \end{itemdecl} @@ -13839,13 +14151,13 @@ \indexlibrary{\idxcode{not_fn}}% \begin{itemdecl} -template @\unspec@ not_fn(F&& f); +template @\unspec@ not_fn(F&& f); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{return \placeholder{call_wrapper}(std::forward(f));} +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}@ { @@ -14210,7 +14522,7 @@ \begin{itemdescr} \pnum\postconditions \tcode{what()} returns an -\impldef{return value of \tcode{bad_function_call::what}} \ntbs. +\impldef{return value of \tcode{bad_function_call::what}} \ntbs{}. \end{itemdescr} \rSec3[func.wrap.func]{Class template \tcode{function}} @@ -14261,20 +14573,20 @@ template function(F) -> function<@\seebelow@>; // \ref{func.wrap.func.nullptr}, Null pointer comparisons - template + template bool operator==(const function&, nullptr_t) noexcept; - template + template bool operator==(nullptr_t, const function&) noexcept; - template + template bool operator!=(const function&, nullptr_t) noexcept; - template + template bool operator!=(nullptr_t, const function&) noexcept; // \ref{func.wrap.func.alg}, specialized algorithms - template + template void swap(function&, function&) noexcept; } \end{codeblock} @@ -14293,7 +14605,7 @@ and return type \tcode{R} if the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)}, -considered as an unevaluated operand\iref{expr}, is +considered as an unevaluated operand\iref{expr.prop}, is well-formed\iref{func.require}. \pnum @@ -14421,7 +14733,7 @@ \remarks This deduction guide participates in overload resolution only if \tcode{\&F::operator()} is well-formed when treated as an unevaluated operand. In that case, if \tcode{decltype(\&F::operator())} is of the form -\tcode{R(G::*)(A...)}~\cv{}~\tcode{\&\opt{}~noexcept\opt} +\tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}} for a class type \tcode{G}, then the deduced type is \tcode{function}. \pnum @@ -14580,9 +14892,9 @@ \indexlibrarymember{operator==}{function}% \begin{itemdecl} -template +template bool operator==(const function& f, nullptr_t) noexcept; -template +template bool operator==(nullptr_t, const function& f) noexcept; \end{itemdecl} @@ -14592,9 +14904,9 @@ \indexlibrarymember{operator"!=}{function}% \begin{itemdecl} -template +template bool operator!=(const function& f, nullptr_t) noexcept; -template +template bool operator!=(nullptr_t, const function& f) noexcept; \end{itemdecl} @@ -14651,13 +14963,13 @@ \indexlibrary{\idxcode{default_searcher}}% \begin{codeblock} -template > +template> class default_searcher { public: default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, BinaryPredicate pred = BinaryPredicate()); - template + template pair operator()(ForwardIterator2 first, ForwardIterator2 last) const; @@ -14710,9 +15022,9 @@ \indexlibrary{\idxcode{boyer_moore_searcher}}% \begin{codeblock} -template ::value_type>, - class BinaryPredicate = equal_to<>> +template::value_type>, + class BinaryPredicate = equal_to<>> class boyer_moore_searcher { public: boyer_moore_searcher(RandomAccessIterator1 pat_first, @@ -14720,7 +15032,7 @@ Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); - template + template pair operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; @@ -14766,7 +15078,7 @@ \indexlibrarymember{operator()}{boyer_moore_searcher}% \begin{itemdecl} -template +template pair operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; \end{itemdecl} @@ -14803,9 +15115,9 @@ \indexlibrary{\idxcode{boyer_moore_horspool_searcher}}% \begin{codeblock} -template ::value_type>, - class BinaryPredicate = equal_to<>> +template::value_type>, + class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher { public: boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, @@ -14813,7 +15125,7 @@ Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); - template + template pair operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; @@ -14859,7 +15171,7 @@ \indexlibrarymember{operator()}{boyer_moore_horspool_searcher}% \begin{itemdecl} -template +template pair operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; \end{itemdecl} @@ -14955,13 +15267,13 @@ \rSec1[meta]{Metaprogramming and type traits} \pnum -This subclause describes components used by \Cpp programs, particularly in +This subclause describes components used by \Cpp{} programs, particularly in templates, to support the widest possible range of types, optimise template code usage, detect type related user errors, and perform type inference and transformation at compile time. It includes type classification traits, type property inspection traits, and type transformations. The type classification traits describe a complete taxonomy -of all possible \Cpp types, and state where in that taxonomy a given +of all possible \Cpp{} types, and state where in that taxonomy a given type belongs. The type property inspection traits allow important characteristics of types or of combinations of types to be inspected. The type transformations allow certain properties of types to be manipulated. @@ -15013,205 +15325,206 @@ \rSec2[meta.type.synop]{Header \tcode{} synopsis} -\indextext{\idxhdr{type_traits}}% -\indexlibrary{\idxhdr{type_traits}}% +\indexhdr{type_traits}% \begin{codeblock} namespace std { // \ref{meta.help}, helper class - template struct integral_constant; + template struct integral_constant; - template + template using bool_constant = integral_constant; using true_type = bool_constant; using false_type = bool_constant; // \ref{meta.unary.cat}, primary type categories - template struct is_void; - template struct is_null_pointer; - template struct is_integral; - template struct is_floating_point; - template struct is_array; - template struct is_pointer; - template struct is_lvalue_reference; - template struct is_rvalue_reference; - template struct is_member_object_pointer; - template struct is_member_function_pointer; - template struct is_enum; - template struct is_union; - template struct is_class; - template struct is_function; + template struct is_void; + template struct is_null_pointer; + template struct is_integral; + template struct is_floating_point; + template struct is_array; + template struct is_pointer; + template struct is_lvalue_reference; + template struct is_rvalue_reference; + template struct is_member_object_pointer; + template struct is_member_function_pointer; + template struct is_enum; + template struct is_union; + template struct is_class; + template struct is_function; // \ref{meta.unary.comp}, composite type categories - template struct is_reference; - template struct is_arithmetic; - template struct is_fundamental; - template struct is_object; - template struct is_scalar; - template struct is_compound; - template struct is_member_pointer; + template struct is_reference; + template struct is_arithmetic; + template struct is_fundamental; + template struct is_object; + template struct is_scalar; + template struct is_compound; + template struct is_member_pointer; // \ref{meta.unary.prop}, type properties - template struct is_const; - template struct is_volatile; - template struct is_trivial; - template struct is_trivially_copyable; - template struct is_standard_layout; - template struct is_pod; - template struct is_empty; - template struct is_polymorphic; - template struct is_abstract; - template struct is_final; - template struct is_aggregate; + template struct is_const; + template struct is_volatile; + template struct is_trivial; + template struct is_trivially_copyable; + template struct is_standard_layout; + template struct is_empty; + template struct is_polymorphic; + template struct is_abstract; + template struct is_final; + template struct is_aggregate; - template struct is_signed; - template struct is_unsigned; + template struct is_signed; + template struct is_unsigned; - template struct is_constructible; - template struct is_default_constructible; - template struct is_copy_constructible; - template struct is_move_constructible; + template struct is_constructible; + template struct is_default_constructible; + template struct is_copy_constructible; + template struct is_move_constructible; - template struct is_assignable; - template struct is_copy_assignable; - template struct is_move_assignable; + template struct is_assignable; + template struct is_copy_assignable; + template struct is_move_assignable; - template struct is_swappable_with; - template struct is_swappable; + template struct is_swappable_with; + template struct is_swappable; - template struct is_destructible; + template struct is_destructible; - template struct is_trivially_constructible; - template struct is_trivially_default_constructible; - template struct is_trivially_copy_constructible; - template struct is_trivially_move_constructible; + template struct is_trivially_constructible; + template struct is_trivially_default_constructible; + template struct is_trivially_copy_constructible; + template struct is_trivially_move_constructible; - template struct is_trivially_assignable; - template struct is_trivially_copy_assignable; - template struct is_trivially_move_assignable; - template struct is_trivially_destructible; + template struct is_trivially_assignable; + template struct is_trivially_copy_assignable; + template struct is_trivially_move_assignable; + template struct is_trivially_destructible; - template struct is_nothrow_constructible; - template struct is_nothrow_default_constructible; - template struct is_nothrow_copy_constructible; - template struct is_nothrow_move_constructible; + template struct is_nothrow_constructible; + template struct is_nothrow_default_constructible; + template struct is_nothrow_copy_constructible; + template struct is_nothrow_move_constructible; - template struct is_nothrow_assignable; - template struct is_nothrow_copy_assignable; - template struct is_nothrow_move_assignable; + template struct is_nothrow_assignable; + template struct is_nothrow_copy_assignable; + template struct is_nothrow_move_assignable; - template struct is_nothrow_swappable_with; - template struct is_nothrow_swappable; + template struct is_nothrow_swappable_with; + template struct is_nothrow_swappable; - template struct is_nothrow_destructible; + template struct is_nothrow_destructible; - template struct has_virtual_destructor; + template struct has_virtual_destructor; - template struct has_unique_object_representations; + template struct has_unique_object_representations; // \ref{meta.unary.prop.query}, type property queries - template struct alignment_of; - template struct rank; - template struct extent; + template struct alignment_of; + template struct rank; + template struct extent; // \ref{meta.rel}, type relations - template struct is_same; - template struct is_base_of; - template struct is_convertible; + template struct is_same; + template struct is_base_of; + template struct is_convertible; - template struct is_invocable; - template struct is_invocable_r; + template struct is_invocable; + template struct is_invocable_r; - template struct is_nothrow_invocable; - template struct is_nothrow_invocable_r; + template struct is_nothrow_invocable; + template struct is_nothrow_invocable_r; // \ref{meta.trans.cv}, const-volatile modifications - template struct remove_const; - template struct remove_volatile; - template struct remove_cv; - template struct add_const; - template struct add_volatile; - template struct add_cv; - - template + template struct remove_const; + template struct remove_volatile; + template struct remove_cv; + template struct add_const; + template struct add_volatile; + template struct add_cv; + + template using remove_const_t = typename remove_const::type; - template + template using remove_volatile_t = typename remove_volatile::type; - template + template using remove_cv_t = typename remove_cv::type; - template + template using add_const_t = typename add_const::type; - template + template using add_volatile_t = typename add_volatile::type; - template + template using add_cv_t = typename add_cv::type; // \ref{meta.trans.ref}, reference modifications - template struct remove_reference; - template struct add_lvalue_reference; - template struct add_rvalue_reference; + template struct remove_reference; + template struct add_lvalue_reference; + template struct add_rvalue_reference; - template + template using remove_reference_t = typename remove_reference::type; - template + template using add_lvalue_reference_t = typename add_lvalue_reference::type; - template + template using add_rvalue_reference_t = typename add_rvalue_reference::type; // \ref{meta.trans.sign}, sign modifications - template struct make_signed; - template struct make_unsigned; + template struct make_signed; + template struct make_unsigned; - template + template using make_signed_t = typename make_signed::type; - template + template using make_unsigned_t = typename make_unsigned::type; // \ref{meta.trans.arr}, array modifications - template struct remove_extent; - template struct remove_all_extents; + template struct remove_extent; + template struct remove_all_extents; - template + template using remove_extent_t = typename remove_extent::type; - template + template using remove_all_extents_t = typename remove_all_extents::type; // \ref{meta.trans.ptr}, pointer modifications - template struct remove_pointer; - template struct add_pointer; + template struct remove_pointer; + template struct add_pointer; - template + template using remove_pointer_t = typename remove_pointer::type; - template + template using add_pointer_t = typename add_pointer::type; // \ref{meta.trans.other}, other transformations - template // see \ref{meta.trans.other} + template // see \ref{meta.trans.other} struct aligned_storage; - template struct aligned_union; - template struct decay; - template struct enable_if; - template struct conditional; - template struct common_type; - template struct underlying_type; - template struct invoke_result; - - template // see \ref{meta.trans.other} + template struct aligned_union; + template struct remove_cvref; + template struct decay; + template struct enable_if; + template struct conditional; + template struct common_type; + template struct underlying_type; + template struct invoke_result; + + template // see \ref{meta.trans.other} using aligned_storage_t = typename aligned_storage::type; - template + template using aligned_union_t = typename aligned_union::type; - template + template + using remove_cvref_t = typename remove_cvref::type; + template using decay_t = typename decay::type; - template + template using enable_if_t = typename enable_if::type; - template + template using conditional_t = typename conditional::type; - template + template using common_type_t = typename common_type::type; - template + template using underlying_type_t = typename underlying_type::type; - template + template using invoke_result_t = typename invoke_result::type; - template + template using void_t = void; // \ref{meta.logical}, logical operator traits @@ -15227,172 +15540,170 @@ }; // \ref{meta.unary.cat}, primary type categories - template + template inline constexpr bool is_void_v = is_void::value; - template + template inline constexpr bool is_null_pointer_v = is_null_pointer::value; - template + template inline constexpr bool is_integral_v = is_integral::value; - template + template inline constexpr bool is_floating_point_v = is_floating_point::value; - template + template inline constexpr bool is_array_v = is_array::value; - template + template inline constexpr bool is_pointer_v = is_pointer::value; - template + template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; - template + template inline constexpr bool is_rvalue_reference_v = is_rvalue_reference::value; - template + template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer::value; - template + template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer::value; - template + template inline constexpr bool is_enum_v = is_enum::value; - template + template inline constexpr bool is_union_v = is_union::value; - template + template inline constexpr bool is_class_v = is_class::value; - template + template inline constexpr bool is_function_v = is_function::value; // \ref{meta.unary.comp}, composite type categories - template + template inline constexpr bool is_reference_v = is_reference::value; - template + template inline constexpr bool is_arithmetic_v = is_arithmetic::value; - template + template inline constexpr bool is_fundamental_v = is_fundamental::value; - template + template inline constexpr bool is_object_v = is_object::value; - template + template inline constexpr bool is_scalar_v = is_scalar::value; - template + template inline constexpr bool is_compound_v = is_compound::value; - template + template inline constexpr bool is_member_pointer_v = is_member_pointer::value; // \ref{meta.unary.prop}, type properties - template + template inline constexpr bool is_const_v = is_const::value; - template + template inline constexpr bool is_volatile_v = is_volatile::value; - template + template inline constexpr bool is_trivial_v = is_trivial::value; - template + template inline constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; - template + template inline constexpr bool is_standard_layout_v = is_standard_layout::value; - template - inline constexpr bool is_pod_v = is_pod::value; - template + template inline constexpr bool is_empty_v = is_empty::value; - template + template inline constexpr bool is_polymorphic_v = is_polymorphic::value; - template + template inline constexpr bool is_abstract_v = is_abstract::value; - template + template inline constexpr bool is_final_v = is_final::value; - template + template inline constexpr bool is_aggregate_v = is_aggregate::value; - template + template inline constexpr bool is_signed_v = is_signed::value; - template + template inline constexpr bool is_unsigned_v = is_unsigned::value; - template + template inline constexpr bool is_constructible_v = is_constructible::value; - template + template inline constexpr bool is_default_constructible_v = is_default_constructible::value; - template + template inline constexpr bool is_copy_constructible_v = is_copy_constructible::value; - template + template inline constexpr bool is_move_constructible_v = is_move_constructible::value; - template + template inline constexpr bool is_assignable_v = is_assignable::value; - template + template inline constexpr bool is_copy_assignable_v = is_copy_assignable::value; - template + template inline constexpr bool is_move_assignable_v = is_move_assignable::value; - template + template inline constexpr bool is_swappable_with_v = is_swappable_with::value; - template + template inline constexpr bool is_swappable_v = is_swappable::value; - template + template inline constexpr bool is_destructible_v = is_destructible::value; - template + template inline constexpr bool is_trivially_constructible_v = is_trivially_constructible::value; - template + template inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible::value; - template + template inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible::value; - template + template inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible::value; - template + template inline constexpr bool is_trivially_assignable_v = is_trivially_assignable::value; - template + template inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable::value; - template + template inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable::value; - template + template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible::value; - template + template inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible::value; - template + template inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible::value; - template + template inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible::value; - template + template inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible::value; - template + template inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable::value; - template + template inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable::value; - template + template inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable::value; - template + template inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with::value; - template + template inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable::value; - template + template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible::value; - template + template inline constexpr bool has_virtual_destructor_v = has_virtual_destructor::value; - template + template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations::value; // \ref{meta.unary.prop.query}, type property queries - template + template inline constexpr size_t alignment_of_v = alignment_of::value; - template + template inline constexpr size_t rank_v = rank::value; - template + template inline constexpr size_t extent_v = extent::value; // \ref{meta.rel}, type relations - template + template inline constexpr bool is_same_v = is_same::value; - template + template inline constexpr bool is_base_of_v = is_base_of::value; - template + template inline constexpr bool is_convertible_v = is_convertible::value; - template + template inline constexpr bool is_invocable_v = is_invocable::value; - template + template inline constexpr bool is_invocable_r_v = is_invocable_r::value; - template + template inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable::value; - template + template inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r::value; @@ -15416,9 +15727,10 @@ \rSec2[meta.help]{Helper classes} +\indexlibrarymember{value_type}{integral_constant}% \begin{codeblock} namespace std { - template struct integral_constant { + template struct integral_constant { static constexpr T value = v; using value_type = T; @@ -15459,7 +15771,7 @@ \pnum The primary type categories correspond to the descriptions given in -section~\ref{basic.types} of the \Cpp standard. +subclause~\ref{basic.types} of the \Cpp{} standard. \pnum For any given type \tcode{T}, the result of applying one of these templates to @@ -15480,63 +15792,63 @@ \lhdr{Template} & \chdr{Condition} & \rhdr{Comments} \\ \capsep \endhead \indexlibrary{\idxcode{is_void}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_void;} & \tcode{T} is \tcode{void} & \\ \rowsep \indexlibrary{\idxcode{is_null_pointer}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_null_pointer;} & \tcode{T} is \tcode{nullptr_t}\iref{basic.fundamental} & \\ \rowsep \indexlibrary{\idxcode{is_integral}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_integral;} & \tcode{T} is an integral type\iref{basic.fundamental} & \\ \rowsep \indexlibrary{\idxcode{is_floating_point}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_floating_point;} & \tcode{T} is a floating-point type\iref{basic.fundamental} & \\ \rowsep \indexlibrary{\idxcode{is_array}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_array;} & \tcode{T} is an array type\iref{basic.compound} of known or unknown extent & Class template \tcode{array}\iref{array} is not an array type. \\ \rowsep \indexlibrary{\idxcode{is_pointer}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_pointer;} & \tcode{T} is a pointer type\iref{basic.compound} & Includes pointers to functions but not pointers to non-static members. \\ \rowsep \indexlibrary{\idxcode{is_lvalue_reference}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_lvalue_reference;} & \tcode{T} is an lvalue reference type\iref{dcl.ref} & \\ \rowsep \indexlibrary{\idxcode{is_rvalue_reference}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_rvalue_reference;} & \tcode{T} is an rvalue reference type\iref{dcl.ref} & \\ \rowsep \indexlibrary{\idxcode{is_member_object_pointer}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_member_object_pointer;}& - \tcode{T} is a pointer to non-static data member & \\ \rowsep + \tcode{T} is a pointer to data member & \\ \rowsep \indexlibrary{\idxcode{is_member_function_pointer}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_member_function_pointer;}& -\tcode{T} is a pointer to non-static member function & \\ \rowsep +\tcode{T} is a pointer to member function & \\ \rowsep \indexlibrary{\idxcode{is_enum}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_enum;} & \tcode{T} is an enumeration type\iref{basic.compound} & \\ \rowsep \indexlibrary{\idxcode{is_union}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_union;} & \tcode{T} is a union type\iref{basic.compound} & \\ \rowsep \indexlibrary{\idxcode{is_class}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_class;} & \tcode{T} is a non-union class type\iref{basic.compound} & \\ \rowsep \indexlibrary{\idxcode{is_function}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_function;} & \tcode{T} is a function type\iref{basic.compound} & \\ \end{libreqtab3e} @@ -15545,7 +15857,7 @@ \pnum These templates provide convenient compositions of the primary type -categories, corresponding to the descriptions given in section~\ref{basic.types}. +categories, corresponding to the descriptions given in subclause~\ref{basic.types}. \pnum For any given type \tcode{T}, the result of applying one of these templates to @@ -15560,34 +15872,33 @@ \lhdr{Template} & \chdr{Condition} & \rhdr{Comments} \\ \capsep \endhead \indexlibrary{\idxcode{is_reference}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_reference;} & \tcode{T} is an lvalue reference or an rvalue reference & \\ \rowsep \indexlibrary{\idxcode{is_arithmetic}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_arithmetic;} & \tcode{T} is an arithmetic type\iref{basic.fundamental} & \\ \rowsep \indexlibrary{\idxcode{is_fundamental}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_fundamental;} & \tcode{T} is a fundamental type\iref{basic.fundamental} & \\ \rowsep \indexlibrary{\idxcode{is_object}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_object;} & \tcode{T} is an object type\iref{basic.types} & \\ \rowsep \indexlibrary{\idxcode{is_scalar}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_scalar;} & \tcode{T} is a scalar type\iref{basic.types} & \\ \rowsep \indexlibrary{\idxcode{is_compound}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_compound;} & \tcode{T} is a compound type\iref{basic.compound} & \\ \rowsep \indexlibrary{\idxcode{is_member_pointer}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_member_pointer;} & - \tcode{T} is a pointer to non-static data member - or non-static member function & \\ + \tcode{T} is a pointer-to-member type\iref{basic.compound} & \\ \end{libreqtab3b} \rSec3[meta.unary.prop]{Type properties} @@ -15625,46 +15936,39 @@ \endhead \indexlibrary{\idxcode{is_const}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_const;} & \tcode{T} is const-qualified\iref{basic.type.qualifier} & \\ \rowsep \indexlibrary{\idxcode{is_volatile}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_volatile;} & \tcode{T} is volatile-qualified\iref{basic.type.qualifier} & \\ \rowsep \indexlibrary{\idxcode{is_trivial}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivial;} & \tcode{T} is a trivial type\iref{basic.types} & \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\tcode{void}. \\ \rowsep \indexlibrary{\idxcode{is_trivially_copyable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_copyable;} & \tcode{T} is a trivially copyable type\iref{basic.types} & \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\tcode{void}. \\ \rowsep \indexlibrary{\idxcode{is_standard_layout}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_standard_layout;} & \tcode{T} is a standard-layout type\iref{basic.types} & \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\tcode{void}. \\ \rowsep -\indexlibrary{\idxcode{is_pod}}% -\tcode{template }\br - \tcode{struct is_pod;} & - \tcode{T} is a POD type\iref{basic.types} & - \tcode{remove_all_extents_t} shall be a complete - type or \cv{}~\tcode{void}. \\ \rowsep - \indexlibrary{\idxcode{is_empty}!class}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_empty;} & \tcode{T} is a class type, but not a union type, with no non-static data members other than bit-fields of length 0, no virtual member functions, @@ -15673,19 +15977,19 @@ If \tcode{T} is a non-union class type, \tcode{T} shall be a complete type. \\ \rowsep \indexlibrary{\idxcode{is_polymorphic}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_polymorphic;} & \tcode{T} is a polymorphic class\iref{class.virtual} & If \tcode{T} is a non-union class type, \tcode{T} shall be a complete type. \\ \rowsep \indexlibrary{\idxcode{is_abstract}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_abstract;} & \tcode{T} is an abstract class\iref{class.abstract} & If \tcode{T} is a non-union class type, \tcode{T} shall be a complete type. \\ \rowsep \indexlibrary{\idxcode{is_final}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_final;} & \tcode{T} is a class type marked with the \grammarterm{class-virt-specifier} \tcode{final}\iref{class}. \begin{note} A union is a class type that @@ -15693,27 +15997,27 @@ If \tcode{T} is a class type, \tcode{T} shall be a complete type. \\ \rowsep \indexlibrary{\idxcode{is_aggregate}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_aggregate;} & \tcode{T} is an aggregate type\iref{dcl.init.aggr} & \tcode{remove_all_extents_t} shall be a complete type or \cv~\tcode{void}. \\ \rowsep \indexlibrary{\idxcode{is_signed}!class}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_signed;} & If \tcode{is_arithmetic_v} is \tcode{true}, the same result as \tcode{T(-1) < T(0)}; otherwise, \tcode{false} & \\ \rowsep \indexlibrary{\idxcode{is_unsigned}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_unsigned;} & If \tcode{is_arithmetic_v} is \tcode{true}, the same result as \tcode{T(0) < T(-1)}; otherwise, \tcode{false} & \\ \rowsep \indexlibrary{\idxcode{is_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_constructible;} & For a function type \tcode{T} or for a \cv{}~\tcode{void} type \tcode{T}, @@ -15724,14 +16028,14 @@ or arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_default_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_default_constructible;} & \tcode{is_constructible_v} is \tcode{true}. & \tcode{T} shall be a complete type, \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_copy_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_copy_constructible;} & For a referenceable type \tcode{T}\iref{defns.referenceable}, the same result as \tcode{is_constructible_v}, otherwise \tcode{false}. & @@ -15739,7 +16043,7 @@ or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_move_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_move_constructible;} & For a referenceable type \tcode{T}, the same result as \tcode{is_constructible_v}, otherwise \tcode{false}. & @@ -15747,11 +16051,11 @@ or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_assignable;} & The expression \tcode{declval() =} \tcode{declval()} is well-formed when treated as an unevaluated - operand\iref{expr}. Access checking is performed as if in a context + operand\iref{expr.prop}. Access checking is performed as if in a context unrelated to \tcode{T} and \tcode{U}. Only the validity of the immediate context of the assignment expression is considered. \begin{note} The compilation of the expression can result in side effects such as the instantiation of class template @@ -15762,7 +16066,7 @@ or arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_copy_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_copy_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_assignable_v}, otherwise \tcode{false}. & @@ -15770,7 +16074,7 @@ or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_move_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_move_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_assignable_v}, otherwise \tcode{false}. & @@ -15778,11 +16082,11 @@ or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_swappable_with}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_swappable_with;} & The expressions \tcode{swap(declval(), declval())} and \tcode{swap(declval(), declval())} are each well-formed - when treated as an unevaluated operand\iref{expr} + when treated as an unevaluated operand\iref{expr.prop} in an overload-resolution context for swappable values\iref{swappable.requirements}. Access checking is performed as if in a context @@ -15802,7 +16106,7 @@ arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_swappable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_swappable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_swappable_with_v}, @@ -15812,21 +16116,21 @@ an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_destructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_destructible;} & Either \tcode{T} is a reference type, or \tcode{T} is a complete object type for which the expression \tcode{declval().\~U()} is well-formed - when treated as an unevaluated operand\iref{expr}, + when treated as an unevaluated operand\iref{expr.prop}, where \tcode{U} is \tcode{remove_all_extents_t}. & \tcode{T} shall be a complete type, \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct}\br \tcode{is_trivially_constructible;} & \tcode{is_constructible_v}\br +\tcode{template}\br \tcode{struct is_trivially_default_constructible;} & \tcode{is_trivially_constructible_v} is \tcode{true}. & \tcode{T} shall be a complete type, @@ -15845,7 +16149,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_copy_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_copy_constructible;} & For a referenceable type \tcode{T}, the same result as \tcode{is_trivially_constructible_v}, otherwise \tcode{false}. & @@ -15854,7 +16158,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_move_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_move_constructible;} & For a referenceable type \tcode{T}, the same result as \tcode{is_trivially_constructible_v}, otherwise \tcode{false}. & @@ -15863,7 +16167,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_assignable;} & \tcode{is_assignable_v} is \tcode{true} and the assignment, as defined by \tcode{is_assignable}, is known to call no operation that is not trivial @@ -15872,7 +16176,7 @@ or arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_copy_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_copy_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_trivially_assignable_v}, otherwise \tcode{false}. & @@ -15881,7 +16185,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_move_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_move_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_trivially_assignable_v}, otherwise \tcode{false}. & @@ -15889,16 +16193,17 @@ \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_trivially_destructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_trivially_destructible;} & - \tcode{is_destructible_v} is \tcode{true} and the indicated destructor is known - to be trivial. & + \tcode{is_destructible_v} is \tcode{true} and + \tcode{remove_all_extents_t} is either a non-class type or + a class type with a trivial destructor. & \tcode{T} shall be a complete type, \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_constructible;} & \tcode{is_constructible_v} is \tcode{true} and the @@ -15910,7 +16215,7 @@ or arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_default_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_default_constructible;} & \tcode{is_nothrow_constructible_v} is \tcode{true}. & \tcode{T} shall be a complete type, @@ -15918,7 +16223,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_copy_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_copy_constructible;} & For a referenceable type \tcode{T}, the same result as \tcode{is_nothrow_constructible_v}, otherwise \tcode{false}. & @@ -15927,7 +16232,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_move_constructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_move_constructible;} & For a referenceable type \tcode{T}, the same result as \tcode{is_nothrow_constructible_v}, otherwise \tcode{false}. & @@ -15935,7 +16240,7 @@ \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_assignable;} & \tcode{is_assignable_v} is \tcode{true} and the assignment is known not to throw any exceptions\iref{expr.unary.noexcept}. & @@ -15943,7 +16248,7 @@ or arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_copy_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_copy_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_nothrow_assignable_v}, otherwise \tcode{false}. & @@ -15952,7 +16257,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_move_assignable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_move_assignable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_nothrow_assignable_v}, otherwise \tcode{false}. & @@ -15961,7 +16266,7 @@ bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_swappable_with}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_swappable_with;} & \tcode{is_swappable_with_v} is \tcode{true} and each \tcode{swap} expression of the definition of @@ -15972,7 +16277,7 @@ arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_swappable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_swappable;} & For a referenceable type \tcode{T}, the same result as \tcode{is_nothrow_swappable_with_v}, @@ -15982,7 +16287,7 @@ an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_destructible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_destructible;} & \tcode{is_destructible_v} is \tcode{true} and the indicated destructor is known not to throw any exceptions\iref{expr.unary.noexcept}. & @@ -15991,13 +16296,13 @@ bound. \\ \rowsep \indexlibrary{\idxcode{has_virtual_destructor}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct has_virtual_destructor;} & \tcode{T} has a virtual destructor\iref{class.dtor} & If \tcode{T} is a non-union class type, \tcode{T} shall be a complete type. \\ \rowsep \indexlibrary{\idxcode{has_unique_object_representations}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct has_unique_object_representations;} & For an array type \tcode{T}, the same result as \tcode{has_unique_object_representations_v>}, @@ -16098,20 +16403,20 @@ \endhead \indexlibrary{\idxcode{alignment_of}}% -\tcode{template \br +\tcode{template\br struct alignment_of;} & \tcode{alignof(T)}.\br \requires{} \tcode{alignof(T)} shall be a valid expression\iref{expr.alignof} \\ \rowsep \indexlibrary{\idxcode{rank}}% -\tcode{template \br +\tcode{template\br struct rank;} & If \tcode{T} names an array type, an integer value representing the number of dimensions of \tcode{T}; otherwise, 0. \\ \rowsep \indexlibrary{\idxcode{extent}}% -\tcode{template \br struct extent;} & If \tcode{T} is not an array type, or if it has rank less @@ -16171,12 +16476,12 @@ \topline \lhdr{Template} & \chdr{Condition} & \rhdr{Comments} \\ \capsep \endhead -\tcode{template }\br +\tcode{template}\br \tcode{struct is_same;} & \tcode{T} and \tcode{U} name the same type with the same cv-qualifications & \\ \rowsep \indexlibrary{\idxcode{is_base_of}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_base_of;} & \tcode{Base} is a base class of \tcode{Derived}\iref{class.derived} without regard to cv-qualifiers @@ -16192,7 +16497,7 @@ are, nonetheless, base classes. \end{note} \\ \rowsep \indexlibrary{\idxcode{is_convertible}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_convertible;} & \seebelow & \tcode{From} and \tcode{To} shall be complete @@ -16200,7 +16505,7 @@ bound, or \cv{}~\tcode{void} types. \\ \rowsep \indexlibrary{\idxcode{is_invocable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_invocable;} & The expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} is well-formed when treated as an unevaluated operand & @@ -16209,7 +16514,7 @@ arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_invocable_r}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_invocable_r;} & The expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} is well-formed when treated as an unevaluated operand & @@ -16218,7 +16523,7 @@ arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_invocable}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_invocable;} & \tcode{is_invocable_v<}\br\tcode{Fn, ArgTypes...>} is \tcode{true} and the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} @@ -16228,7 +16533,7 @@ arrays of unknown bound. \\ \rowsep \indexlibrary{\idxcode{is_nothrow_invocable_r}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct is_nothrow_invocable_r;} & \tcode{is_invocable_r_v<}\br\tcode{R, Fn, ArgTypes...>} is \tcode{true} and the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} @@ -16309,7 +16614,7 @@ \endhead \indexlibrary{\idxcode{remove_const}}% -\tcode{template \br +\tcode{template\br struct remove_const;} & The member typedef \tcode{type} names the same type as \tcode{T} @@ -16319,7 +16624,7 @@ \tcode{const int*}. \end{example} \\ \rowsep \indexlibrary{\idxcode{remove_volatile}}% -\tcode{template \br +\tcode{template\br struct remove_volatile;} & The member typedef \tcode{type} names the same type as \tcode{T} @@ -16330,7 +16635,7 @@ \end{example} \\ \rowsep \indexlibrary{\idxcode{remove_cv}}% -\tcode{template \br +\tcode{template\br struct remove_cv;} & The member typedef \tcode{type} shall be the same as \tcode{T} except that any top-level cv-qualifier has been removed. @@ -16339,7 +16644,7 @@ evaluates to \tcode{const volatile int*}. \end{example} \\ \rowsep \indexlibrary{\idxcode{add_const}}% -\tcode{template \br +\tcode{template\br struct add_const;} & If \tcode{T} is a reference, function, or top-level const-qualified type, then \tcode{type} names @@ -16347,7 +16652,7 @@ \tcode{T const}. \\ \rowsep \indexlibrary{\idxcode{add_volatile}}% -\tcode{template \br +\tcode{template\br struct add_volatile;} & If \tcode{T} is a reference, function, or top-level volatile-qualified type, then \tcode{type} names @@ -16355,7 +16660,7 @@ \tcode{T volatile}. \\ \rowsep \indexlibrary{\idxcode{add_cv}}% -\tcode{template \br +\tcode{template\br struct add_cv;} & The member typedef \tcode{type} names the same type as @@ -16374,14 +16679,14 @@ \endhead \indexlibrary{\idxcode{remove_reference}}% -\tcode{template \br +\tcode{template\br struct remove_reference;} & If \tcode{T} has type ``reference to \tcode{T1}'' then the member typedef \tcode{type} names \tcode{T1}; otherwise, \tcode{type} names \tcode{T}.\\ \rowsep \indexlibrary{\idxcode{add_lvalue_reference}}% -\tcode{template \br +\tcode{template\br struct add_lvalue_reference;} & If \tcode{T} names a referenceable type\iref{defns.referenceable} then the member typedef \tcode{type} names \tcode{T\&}; @@ -16391,7 +16696,7 @@ \end{note}\\ \rowsep \indexlibrary{\idxcode{add_rvalue_reference}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct add_rvalue_reference;} & If \tcode{T} names a referenceable type then the member typedef \tcode{type} names \tcode{T\&\&}; @@ -16413,7 +16718,7 @@ \endhead \indexlibrary{\idxcode{make_signed}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct make_signed;} & If \tcode{T} names a (possibly cv-qualified) signed integer type\iref{basic.fundamental} then the member typedef @@ -16430,7 +16735,7 @@ but not a \tcode{bool} type.\\ \rowsep \indexlibrary{\idxcode{make_unsigned}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct make_unsigned;} & If \tcode{T} names a (possibly cv-qualified) unsigned integer type\iref{basic.fundamental} then the member typedef @@ -16458,7 +16763,7 @@ \endhead \indexlibrary{\idxcode{remove_extent}}% -\tcode{template \br +\tcode{template\br struct remove_extent;} & If \tcode{T} names a type ``array of \tcode{U}'', the member typedef \tcode{type} shall @@ -16468,7 +16773,7 @@ \tcode{const U}. \end{note} \\ \rowsep \indexlibrary{\idxcode{remove_all_extents}}% -\tcode{template \br +\tcode{template\br struct remove_all_extents;} & If \tcode{T} is ``multi-dimensional array of \tcode{U}'', the resulting member typedef \tcode{type} is \tcode{U}, otherwise \tcode{T}. \\ @@ -16507,14 +16812,14 @@ \endhead \indexlibrary{\idxcode{remove_pointer}}% -\tcode{template \br +\tcode{template\br struct remove_pointer;} & If \tcode{T} has type ``(possibly cv-qualified) pointer to \tcode{T1}'' then the member typedef \tcode{type} names \tcode{T1}; otherwise, it names \tcode{T}.\\ \rowsep \indexlibrary{\idxcode{add_pointer}}% -\tcode{template \br +\tcode{template\br struct add_pointer;} & If \tcode{T} names a referenceable type\iref{defns.referenceable} or a \cv{}~\tcode{void} type then @@ -16535,35 +16840,43 @@ \endhead \indexlibrary{\idxcode{aligned_storage}}% -\tcode{template \br struct aligned_storage;} & The value of \textit{default-alignment} shall be the most - stringent alignment requirement for any \Cpp object type whose size + stringent alignment requirement for any \Cpp{} object type whose size is no greater than \tcode{Len}\iref{basic.types}. - The member typedef \tcode{type} shall be a POD type + The member typedef \tcode{type} shall be a trivial type suitable for use as uninitialized storage for any object whose size is at most \tcode{Len} and whose alignment is a divisor of \tcode{Align}.\br \requires{} \tcode{Len} shall not be zero. \tcode{Align} shall be equal to \tcode{alignof(T)} for some type \tcode{T} or to \textit{default-alignment}.\\ \rowsep \indexlibrary{\idxcode{aligned_union}}% -\tcode{template \br struct aligned_union;} & - The member typedef \tcode{type} shall be a POD type suitable for use as + The member typedef \tcode{type} shall be a trivial type suitable for use as uninitialized storage for any object whose type is listed in \tcode{Types}; its size shall be at least \tcode{Len}. The static member \tcode{alignment_value} shall be an integral constant of type \tcode{size_t} whose value is the strictest alignment of all types listed in \tcode{Types}.\br \requires{} At least one type is provided. + Each type in the parameter pack \tcode{Types} shall be a complete object type. \\ \rowsep +\indexlibrary{\idxcode{remove_cvref}}% +\tcode{template\br struct remove_cvref;} + & + The member typedef \tcode{type} names the same type as + \tcode{remove_cv_t>}. + \\ \rowsep + \indexlibrary{\idxcode{decay}}% -\tcode{template \br struct decay;} +\tcode{template\br struct decay;} & Let \tcode{U} be \tcode{remove_reference_t}. If \tcode{is_array_v} is \tcode{true}, the member typedef \tcode{type} shall equal @@ -16578,20 +16891,20 @@ \\ \rowsep \indexlibrary{\idxcode{enable_if}}% -\tcode{template } \tcode{struct enable_if;} +\tcode{template} \tcode{struct enable_if;} & If \tcode{B} is \tcode{true}, the member typedef \tcode{type} shall equal \tcode{T}; otherwise, there shall be no member \tcode{type}. \\ \rowsep -\tcode{template }\br \tcode{struct conditional;} & If \tcode{B} is \tcode{true}, the member typedef \tcode{type} shall equal \tcode{T}. If \tcode{B} is \tcode{false}, the member typedef \tcode{type} shall equal \tcode{F}. \\ \rowsep - \tcode{template } \tcode{struct common_type;} + \tcode{template} \tcode{struct common_type;} & Unless this trait is specialized (as specified in Note B, below), the member \tcode{type} shall be defined or omitted as specified in Note A, below. @@ -16600,19 +16913,19 @@ complete, \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep \indexlibrary{\idxcode{underlying_type}}% -\tcode{template }\br +\tcode{template}\br \tcode{struct underlying_type;} & The member typedef \tcode{type} names the underlying type of \tcode{T}.\br \requires{} \tcode{T} shall be a complete enumeration type\iref{dcl.enum} \\ \rowsep -\tcode{template }\br \tcode{struct invoke_result;} & If the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} - is well-formed when treated as an unevaluated operand\iref{expr}, + is well-formed when treated as an unevaluated operand\iref{expr.prop}, the member typedef \tcode{type} names the type \tcode{decltype(\placeholdernc{INVOKE}(declval(), declval()...))}; otherwise, there shall be no member \tcode{type}. Access checking is @@ -16636,7 +16949,7 @@ \begin{note} A typical implementation would define \tcode{aligned_storage} as: \begin{codeblock} -template +template struct aligned_storage { typedef struct { alignas(Alignment) unsigned char __data[Len]; @@ -16883,7 +17196,7 @@ \begin{itemdescr} \pnum -If all scalar types have size \tcode{1}, then all of \tcode{endian::little}, +If all scalar types have size 1 byte, then all of \tcode{endian::little}, \tcode{endian::big}, and \tcode{endian::native} have the same value. Otherwise, \tcode{endian::little} is not equal to \tcode{endian::big}. If all scalar types are big-endian, \tcode{endian::native} is @@ -16913,38 +17226,37 @@ \rSec2[ratio.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{ratio}}% -\indexlibrary{\idxhdr{ratio}}% +\indexhdr{ratio}% \begin{codeblockdigitsep} namespace std { // \ref{ratio.ratio}, class template \tcode{ratio} - template class ratio; + template class ratio; // \ref{ratio.arithmetic}, ratio arithmetic - template using ratio_add = @\seebelow@; - template using ratio_subtract = @\seebelow@; - template using ratio_multiply = @\seebelow@; - template using ratio_divide = @\seebelow@; + template using ratio_add = @\seebelow@; + template using ratio_subtract = @\seebelow@; + template using ratio_multiply = @\seebelow@; + template using ratio_divide = @\seebelow@; // \ref{ratio.comparison}, ratio comparison - template struct ratio_equal; - template struct ratio_not_equal; - template struct ratio_less; - template struct ratio_less_equal; - template struct ratio_greater; - template struct ratio_greater_equal; - - template + template struct ratio_equal; + template struct ratio_not_equal; + template struct ratio_less; + template struct ratio_less_equal; + template struct ratio_greater; + template struct ratio_greater_equal; + + template inline constexpr bool ratio_equal_v = ratio_equal::value; - template + template inline constexpr bool ratio_not_equal_v = ratio_not_equal::value; - template + template inline constexpr bool ratio_less_v = ratio_less::value; - template + template inline constexpr bool ratio_less_equal_v = ratio_less_equal::value; - template + template inline constexpr bool ratio_greater_v = ratio_greater::value; - template + template inline constexpr bool ratio_greater_equal_v = ratio_greater_equal::value; // \ref{ratio.si}, convenience SI typedefs @@ -16976,7 +17288,7 @@ \indexlibrary{\idxcode{ratio}}% \begin{codeblock} namespace std { - template class ratio { + template class ratio { public: static constexpr intmax_t num; static constexpr intmax_t den; @@ -17077,19 +17389,19 @@ \indexlibrary{\idxcode{ratio_equal}}% \begin{itemdecl} -template +template struct ratio_equal : bool_constant { }; \end{itemdecl} \indexlibrary{\idxcode{ratio_not_equal}}% \begin{itemdecl} -template +template struct ratio_not_equal : bool_constant> { }; \end{itemdecl} \indexlibrary{\idxcode{ratio_less}}% \begin{itemdecl} -template +template struct ratio_less : bool_constant<@\seebelow@> { }; \end{itemdecl} @@ -17104,19 +17416,19 @@ \indexlibrary{\idxcode{ratio_less_equal}}% \begin{itemdecl} -template +template struct ratio_less_equal : bool_constant> { }; \end{itemdecl} \indexlibrary{\idxcode{ratio_greater}}% \begin{itemdecl} -template +template struct ratio_greater : bool_constant> { }; \end{itemdecl} \indexlibrary{\idxcode{ratio_greater_equal}}% \begin{itemdecl} -template +template struct ratio_greater_equal : bool_constant> { }; \end{itemdecl} @@ -17141,88 +17453,87 @@ \rSec2[time.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{chrono}}% -\indexlibrary{\idxhdr{chrono}}% +\indexhdr{chrono}% \begin{codeblock} namespace std { namespace chrono { // \ref{time.duration}, class template \tcode{duration} - template > class duration; + template> class duration; // \ref{time.point}, class template \tcode{time_point} - template class time_point; + template class time_point; } // \ref{time.traits.specializations}, \tcode{common_type} specializations - template + template struct common_type, chrono::duration>; - template + template struct common_type, chrono::time_point>; namespace chrono { // \ref{time.traits}, customization traits - template struct treat_as_floating_point; - template struct duration_values; - template + template struct treat_as_floating_point; + template struct duration_values; + template inline constexpr bool treat_as_floating_point_v = treat_as_floating_point::value; // \ref{time.duration.nonmember}, \tcode{duration} arithmetic - template + template constexpr common_type_t, duration> operator+(const duration& lhs, const duration& rhs); - template + template constexpr common_type_t, duration> operator-(const duration& lhs, const duration& rhs); - template + template constexpr duration, Period> operator*(const duration& d, const Rep2& s); - template + template constexpr duration, Period> operator*(const Rep1& s, const duration& d); - template + template constexpr duration, Period> operator/(const duration& d, const Rep2& s); - template + template constexpr common_type_t operator/(const duration& lhs, const duration& rhs); - template + template constexpr duration, Period> operator%(const duration& d, const Rep2& s); - template + template constexpr common_type_t, duration> operator%(const duration& lhs, const duration& rhs); // \ref{time.duration.comparisons}, \tcode{duration} comparisons - template + template constexpr bool operator==(const duration& lhs, const duration& rhs); - template + template constexpr bool operator!=(const duration& lhs, const duration& rhs); - template + template constexpr bool operator< (const duration& lhs, const duration& rhs); - template + template constexpr bool operator<=(const duration& lhs, const duration& rhs); - template + template constexpr bool operator> (const duration& lhs, const duration& rhs); - template + template constexpr bool operator>=(const duration& lhs, const duration& rhs); // \ref{time.duration.cast}, \tcode{duration_cast} - template + template constexpr ToDuration duration_cast(const duration& d); - template + template constexpr ToDuration floor(const duration& d); - template + template constexpr ToDuration ceil(const duration& d); - template + template constexpr ToDuration round(const duration& d); // convenience typedefs @@ -17234,53 +17545,53 @@ using hours = duration<@\term{signed integer type of at least 23 bits}@, ratio<3600>>; // \ref{time.point.nonmember}, \tcode{time_point} arithmetic - template + template constexpr time_point>> operator+(const time_point& lhs, const duration& rhs); - template + template constexpr time_point, Duration2>> operator+(const duration& lhs, const time_point& rhs); - template + template constexpr time_point>> operator-(const time_point& lhs, const duration& rhs); - template + template constexpr common_type_t operator-(const time_point& lhs, const time_point& rhs); // \ref{time.point.comparisons}, \tcode{time_point} comparisons - template + template constexpr bool operator==(const time_point& lhs, const time_point& rhs); - template + template constexpr bool operator!=(const time_point& lhs, const time_point& rhs); - template + template constexpr bool operator< (const time_point& lhs, const time_point& rhs); - template + template constexpr bool operator<=(const time_point& lhs, const time_point& rhs); - template + template constexpr bool operator> (const time_point& lhs, const time_point& rhs); - template + template constexpr bool operator>=(const time_point& lhs, const time_point& rhs); // \ref{time.point.cast}, \tcode{time_point_cast} - template + template constexpr time_point time_point_cast(const time_point& t); - template + template constexpr time_point floor(const time_point& tp); - template + template constexpr time_point ceil(const time_point& tp); - template + template constexpr time_point round(const time_point& tp); // \ref{time.duration.alg}, specialized algorithms - template + template constexpr duration abs(duration d); // \ref{time.clock}, clocks @@ -17404,7 +17715,7 @@ \indexlibrary{\idxcode{treat_as_floating_point}}% \begin{itemdecl} -template struct treat_as_floating_point : is_floating_point { }; +template struct treat_as_floating_point : is_floating_point { }; \end{itemdecl} \pnum @@ -17425,7 +17736,7 @@ \indexlibrary{\idxcode{duration_values}}% \begin{itemdecl} -template +template struct duration_values { public: static constexpr Rep zero(); @@ -17487,7 +17798,7 @@ \indexlibrary{\idxcode{common_type}}% \begin{itemdecl} -template +template struct common_type, chrono::duration> { using type = chrono::duration, @\seebelow@>; }; @@ -17511,7 +17822,7 @@ \indexlibrary{\idxcode{common_type}}% \begin{itemdecl} -template +template struct common_type, chrono::time_point> { using type = chrono::time_point>; }; @@ -17532,7 +17843,7 @@ \indexlibrary{\idxcode{duration}}% \begin{codeblock} namespace std::chrono { - template > + template> class duration { public: using rep = Rep; @@ -17544,9 +17855,9 @@ public: // \ref{time.duration.cons}, construct/copy/destroy constexpr duration() = default; - template + template constexpr explicit duration(const Rep2& r); - template + template constexpr duration(const duration& d); ~duration() = default; duration(const duration&) = default; @@ -17612,7 +17923,7 @@ \indexlibrary{\idxcode{duration}!constructor}% \begin{itemdecl} -template +template constexpr explicit duration(const Rep2& r); \end{itemdecl} @@ -17641,7 +17952,7 @@ \indexlibrary{\idxcode{duration}!constructor}% \begin{itemdecl} -template +template constexpr duration(const duration& d); \end{itemdecl} @@ -17867,7 +18178,7 @@ \indexlibrary{\idxcode{common_type}}% \begin{itemdecl} -template +template constexpr common_type_t, duration> operator+(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -17879,7 +18190,7 @@ \indexlibrary{\idxcode{common_type}}% \begin{itemdecl} -template +template constexpr common_type_t, duration> operator-(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -17891,7 +18202,7 @@ \indexlibrarymember{operator*}{duration}% \begin{itemdecl} -template +template constexpr duration, Period> operator*(const duration& d, const Rep2& s); \end{itemdecl} @@ -17907,7 +18218,7 @@ \indexlibrarymember{operator*}{duration}% \begin{itemdecl} -template +template constexpr duration, Period> operator*(const Rep1& s, const duration& d); \end{itemdecl} @@ -17923,7 +18234,7 @@ \indexlibrarymember{operator/}{duration}% \begin{itemdecl} -template +template constexpr duration, Period> operator/(const duration& d, const Rep2& s); \end{itemdecl} @@ -17940,7 +18251,7 @@ \indexlibrarymember{operator/}{duration}% \begin{itemdecl} -template +template constexpr common_type_t operator/(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -17952,7 +18263,7 @@ \indexlibrarymember{operator\%}{duration}% \begin{itemdecl} -template +template constexpr duration, Period> operator%(const duration& d, const Rep2& s); \end{itemdecl} @@ -17969,7 +18280,7 @@ \indexlibrarymember{operator\%}{duration}% \begin{itemdecl} -template +template constexpr common_type_t, duration> operator%(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -17989,7 +18300,7 @@ \indexlibrarymember{operator==}{duration}% \begin{itemdecl} -template +template constexpr bool operator==(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18001,7 +18312,7 @@ \indexlibrarymember{operator"!=}{duration}% \begin{itemdecl} -template +template constexpr bool operator!=(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18013,7 +18324,7 @@ \indexlibrarymember{operator<}{duration}% \begin{itemdecl} -template +template constexpr bool operator<(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18025,7 +18336,7 @@ \indexlibrarymember{operator<=}{duration}% \begin{itemdecl} -template +template constexpr bool operator<=(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18037,7 +18348,7 @@ \indexlibrarymember{operator>}{duration}% \begin{itemdecl} -template +template constexpr bool operator>(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18049,7 +18360,7 @@ \indexlibrarymember{operator>=}{duration}% \begin{itemdecl} -template +template constexpr bool operator>=(const duration& lhs, const duration& rhs); \end{itemdecl} @@ -18064,7 +18375,7 @@ \indexlibrary{\idxcode{duration}!\idxcode{duration_cast}}% \indexlibrary{\idxcode{duration_cast}}% \begin{itemdecl} -template +template constexpr ToDuration duration_cast(const duration& d); \end{itemdecl} @@ -18114,7 +18425,7 @@ \indexlibrarymember{floor}{duration}% \begin{itemdecl} -template +template constexpr ToDuration floor(const duration& d); \end{itemdecl} @@ -18130,7 +18441,7 @@ \indexlibrarymember{ceil}{duration}% \begin{itemdecl} -template +template constexpr ToDuration ceil(const duration& d); \end{itemdecl} @@ -18146,7 +18457,7 @@ \indexlibrarymember{round}{duration}% \begin{itemdecl} -template +template constexpr ToDuration round(const duration& d); \end{itemdecl} @@ -18166,7 +18477,7 @@ \rSec3[time.duration.literals]{Suffixes for duration literals} \pnum -This section describes literal suffixes for constructing duration literals. The +This subclause describes literal suffixes for constructing duration literals. The suffixes \tcode{h}, \tcode{min}, \tcode{s}, \tcode{ms}, \tcode{us}, \tcode{ns} denote duration values of the corresponding types \tcode{hours}, \tcode{minutes}, \tcode{seconds}, \tcode{milliseconds}, \tcode{microseconds}, and \tcode{nanoseconds} @@ -18275,7 +18586,7 @@ \indexlibrarymember{abs}{duration}% \begin{itemdecl} -template +template constexpr duration abs(duration d); \end{itemdecl} @@ -18294,7 +18605,7 @@ \indexlibrary{\idxcode{time_point}}% \begin{codeblock} namespace std::chrono { - template + template class time_point { public: using clock = Clock; @@ -18309,7 +18620,7 @@ // \ref{time.point.cons}, construct constexpr time_point(); // has value epoch constexpr explicit time_point(const duration& d); // same as \tcode{time_point() + d} - template + template constexpr time_point(const time_point& t); // \ref{time.point.observer}, observer @@ -18361,7 +18672,7 @@ \indexlibrary{\idxcode{time_point}!constructor}% \begin{itemdecl} -template +template constexpr time_point(const time_point& t); \end{itemdecl} @@ -18442,7 +18753,7 @@ \indexlibrarymember{operator+}{time_point}% \indexlibrarymember{operator+}{duration}% \begin{itemdecl} -template +template constexpr time_point>> operator+(const time_point& lhs, const duration& rhs); \end{itemdecl} @@ -18455,7 +18766,7 @@ \indexlibrarymember{operator+}{time_point}% \indexlibrarymember{operator+}{duration}% \begin{itemdecl} -template +template constexpr time_point, Duration2>> operator+(const duration& lhs, const time_point& rhs); \end{itemdecl} @@ -18468,7 +18779,7 @@ \indexlibrarymember{operator-}{time_point}% \indexlibrarymember{operator-}{duration}% \begin{itemdecl} -template +template constexpr time_point>> operator-(const time_point& lhs, const duration& rhs); \end{itemdecl} @@ -18481,7 +18792,7 @@ \indexlibrarymember{operator-}{time_point}% \begin{itemdecl} -template +template constexpr common_type_t operator-(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18495,7 +18806,7 @@ \indexlibrarymember{operator==}{time_point}% \begin{itemdecl} -template +template constexpr bool operator==(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18507,7 +18818,7 @@ \indexlibrarymember{operator"!=}{time_point}% \begin{itemdecl} -template +template constexpr bool operator!=(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18519,7 +18830,7 @@ \indexlibrarymember{operator<}{time_point}% \begin{itemdecl} -template +template constexpr bool operator<(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18531,7 +18842,7 @@ \indexlibrarymember{operator<=}{time_point}% \begin{itemdecl} -template +template constexpr bool operator<=(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18543,7 +18854,7 @@ \indexlibrarymember{operator>}{time_point}% \begin{itemdecl} -template +template constexpr bool operator>(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18555,7 +18866,7 @@ \indexlibrarymember{operator>=}{time_point}% \begin{itemdecl} -template +template constexpr bool operator>=(const time_point& lhs, const time_point& rhs); \end{itemdecl} @@ -18570,7 +18881,7 @@ \indexlibrary{\idxcode{time_point}!\idxcode{time_point_cast}}% \indexlibrary{\idxcode{time_point_cast}}% \begin{itemdecl} -template +template constexpr time_point time_point_cast(const time_point& t); \end{itemdecl} @@ -18588,7 +18899,7 @@ \indexlibrarymember{floor}{time_point}% \begin{itemdecl} -template +template constexpr time_point floor(const time_point& tp); \end{itemdecl} @@ -18603,7 +18914,7 @@ \indexlibrarymember{ceil}{time_point}% \begin{itemdecl} -template +template constexpr time_point ceil(const time_point& tp); \end{itemdecl} @@ -18618,7 +18929,7 @@ \indexlibrarymember{round}{time_point}% \begin{itemdecl} -template +template constexpr time_point round(const time_point& tp); \end{itemdecl} @@ -18658,7 +18969,7 @@ static time_point now() noexcept; - // Map to C API + // map to C API static time_t to_time_t (const time_point& t) noexcept; static time_point from_time_t(time_t t) noexcept; }; @@ -18755,8 +19066,7 @@ \rSec2[ctime.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{ctime}}% -\indexlibrary{\idxhdr{ctime}}% +\indexhdr{ctime}% \indexlibrary{\idxcode{CLOCKS_PER_SEC}}% \indexlibrary{\idxcode{NULL}}% \indexlibrary{\idxcode{TIME_UTC}}% @@ -18802,10 +19112,8 @@ \end{codeblock} \pnum -\indextext{\idxhdr{time.h}}% -\indexlibrary{\idxhdr{time.h}}% -\indextext{\idxhdr{ctime}}% -\indexlibrary{\idxhdr{ctime}}% +\indexhdr{time.h}% +\indexhdr{ctime}% The contents of the header \tcode{} are the same as the C standard library header \tcode{}.% \footnote{\tcode{strftime} supports the C conversion specifiers \tcode{C}, \tcode{D}, \tcode{e}, \tcode{F}, \tcode{g}, \tcode{G}, \tcode{h}, @@ -18823,12 +19131,11 @@ \rSec2[type.index.synopsis]{Header \tcode{} synopsis} -\indextext{\idxhdr{typeindex}}% -\indexlibrary{\idxhdr{typeindex}}% +\indexhdr{typeindex}% \begin{codeblock} namespace std { class type_index; - template struct hash; + template struct hash; template<> struct hash; } \end{codeblock} @@ -18961,7 +19268,7 @@ \indexlibrary{\idxcode{hash}!\idxcode{type_index}}% \begin{itemdecl} -template <> struct hash; +template<> struct hash; \end{itemdecl} \begin{itemdescr} @@ -19005,8 +19312,7 @@ \rSec2[execution.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{execution}}% -\indexlibrary{\idxhdr{execution}}% +\indexhdr{execution}% \begin{codeblock} namespace std { // \ref{execpol.type}, execution policy type trait @@ -19144,8 +19450,7 @@ \rSec2[charconv.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{charconv}}% -\indexlibrary{\idxhdr{charconv}}% +\indexhdr{charconv}% \begin{codeblock} @% \indexlibrary{\idxcode{chars_format}}% diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index c8eb4782cb..01cc0d287c 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -23,6 +23,10 @@ %\movedxrefii{old.label}{new.label.1}{new.label.2} %\movedxrefiii{old.label}{new.label.1}{new.label.2}{new.label.3} %\movedxrefs{old.label}{new place (eg Table~\ref{tab:blah})} + +% P0588 replaced function prototype scope with function parameter scope. +\movedxref{basic.scope.proto}{basic.scope.param} + \movedxref{utility.from.chars}{charconv.from.chars} \movedxref{utility.to.chars}{charconv.to.chars} @@ -36,5 +40,14 @@ \secref{fs.path.generic}, \secref{fs.race.behavior}} +% Single-item array subclauses were dissolved. +\movedxref{array.size}{array.members} +\movedxref{array.data}{array.members} +\movedxref{array.fill}{array.members} +\movedxref{array.swap}{array.members} + +% Contents of [util.smartptr] was integrated into the parent. +\removedxref{util.smartptr} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)