diff --git a/.travis.yml b/.travis.yml index cc9df4af03..2c99e00e4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ env: - 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=check-whitespace # check for whitespace at the ends of lines script: # Build std.pdf @@ -35,6 +36,10 @@ script: pdflatex std; fi - popd + # Fail if there is whitespace at the ends of any lines + - if [ "$BUILD_TYPE" = "check-whitespace" ]; then + ! grep '\s$' source/*.tex; + fi # Check to see if generated files are out-dated - pushd source - for FIGURE in *.dot; do diff --git a/README.rst b/README.rst index ee1f554bff..162aefdca4 100644 --- a/README.rst +++ b/README.rst @@ -26,6 +26,22 @@ then run the following command to install the other packages that the draft requ sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs extract layouts enumitem +--------------------------------------- +Getting Started on Debian-based Systems +--------------------------------------- + +Install the following packages: + + sudo apt-get install latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended + +------------------------- +Getting Started on Fedora +------------------------- + +Install the following packages: + + dnf install texlive texlive-isodate texlive-relsize texlive-ulem texlive-fixme texlive-extract + ------------ Instructions ------------ diff --git a/papers/n4659.pdf b/papers/n4659.pdf new file mode 100644 index 0000000000..532d5d4040 Binary files /dev/null and b/papers/n4659.pdf differ diff --git a/papers/n4661.html b/papers/n4661.html new file mode 100644 index 0000000000..a29605270a --- /dev/null +++ b/papers/n4661.html @@ -0,0 +1,1005 @@ +N4661 +

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

+ +

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

+ +

Acknowledgements

+ +

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

+ +

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

+ +

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

+ +

New papers

+ + + +

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

+ +

Motions incorporated into working draft and C++17 DIS

+ +

Core working group motions

+ +

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

+ + + +

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

+ +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

CWG motion 7: P0615R0 "Renaming for structured bindings"

+ +

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

+ + + +

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

+ + + +

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

+ + + +

CWG motion 11a applies to the Modules TS.

+ +

CWG motion 11b was not approved.

+ +

Library working group motions

+ +

Issue resolutions

+ +

LWG motion 1 applies to the Coroutines TS.

+ +

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

+ + + +

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

+ +

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

+ + + +

Filesystem

+ +

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

+ +

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

+ + + +

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

+ + + +

Parallel algorithms

+ +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

NB response papers

+ +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ + + +

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

+ +

NB issue resolutions

+ +

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

+ + + +

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

+ +

LWG motion 20a was not approved.

+ +

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

+ + + +

Non-NB-comment papers

+ +

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

+ +

LWG motion 22: P0548R1 "common_type and duration"

+ +

LWG motion 23 applies to the Ranges TS.

+ +

Notable editorial changes

+ +

Motions

+ + + +

NB comments

+ + + +

ISO Directives

+ + + +

Content rearrangement

+ + + +

Stable name changes

+ + + +

Minor editorial fixes

+ +

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

+ +
commit dbf3efe18813054c95abae388c53bf30e96e7e83
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 15:19:47 2017 -0700
+
+    [intro.refs], [intro.defs] Update introductory text to match latest ISO
+    Directives.
+
+commit 32825151765e214d79103a137aa29a9a4357687f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 15:00:51 2017 -0700
+
+    Replace "this International Standard" with "this document" in some
+    places where it is a clear improvement.
+
+    The 7th Edition of the ISO Directives no longer require us to use
+    "this International Standard" when the document refers to itself. We
+    retain that phrasing when the reference is to the abstract notion of
+    the specification as opposed to the text embodying it.
+
+    This is a step towards addressing #1389.
+
+commit 1798a9b6795d6ee92bf093e2a6256c34212552b1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 14:14:22 2017 -0700
+
+    [fs.path.generic] Refactor generic pathname grammar to remove redundancy and ambiguity.
+
+commit 660d97e40353337b0b6b533903ab16e330855a77
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Aug 6 18:02:50 2016 +0200
+
+    [depr.func.adaptor.typedefs] Clarify that reference_wrapper does not define argument_type for non-nullary member function pointer types.
+
+commit 95cbc03c20f20d98a53a3e696df6003ec27abc42
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 16:35:25 2017 +0100
+
+    [istreambuf.iterator] Join subsections for operations descriptions.
+
+    There was one subsection for every operator, yet everything
+    fits on half a page.
+
+    Fixes #1429, #1449.
+
+commit d2b6fb6eefc3c28eb448352cd6d8b0d08e860a66
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 16 21:27:11 2017 +0000
+
+    [containers] Rephrase deduction guide constraints
+
+    Replace "is called with" wording that doesn't apply to deduction guides.
+
+    Move rules about qualifying as input iterators or allocators to
+    [container.requirements.general].
+
+commit a7f52d1904e5a6d2d407eb4145ba54552d0b3e69
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 00:07:04 2017 -0700
+
+    [fs.path.generic] Move descriptions of grammar elements out of the
+    grammar and into separate paragraphs, and format path grammar as we
+    format the language grammar.
+
+    Also rephrase description of root-name to use the defined term
+    "implementation-defined" directly rather than separating it into
+    "implementations [...] define".
+
+commit 04a9e5d759b4fea810ed029dd6b6a0d5ebfd224a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 10 22:46:20 2017 +0100
+
+    [fs.op.copy], [fs.op.copy_file] Rephrase requirements on copy_options.
+
+    Use bitmask 'element' phrasing for restrictions on copy_options.
+
+    Fixes #1445.
+
+commit df9a809a36c34acc0870c5d7869e7549574e1437
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 18 23:08:32 2017 +0100
+
+    [partial.sort] Remove 'It takes' from complexity specification.
+
+    Partially addresses #1088.
+
+commit 5cf60394dbe171ec16bfbba1459772e40b9cf6e1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Mar 18 21:21:14 2017 +0000
+
+    [temp.class.spec.mfunc] Add missing comment to example
+
+commit cdd6dda21e3273ea63b733c3cfb3b630bb1847eb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 16 15:37:17 2017 -0700
+
+    [xref] Add glossary of cross-references between C++14 section labels and
+    C++17 section labels.
+
+    Fixes #1547.
+
+commit 88c20950fac6915844143bb73129e2eb1b41d17d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 16 02:51:38 2017 +0000
+
+    [filesystem] Shorten stable names and add "fs." prefixes
+
+    [class.path] -> [fs.class.path]
+    [path.generic] -> [fs.path.generic]
+    [path.cvt] -> [fs.path.cvt]
+    [path.fmt.cvt] -> [fs.path.fmt.cvt]
+    [path.type.cvt] -> [fs.path.type.cvt]
+    [path.req] -> [fs.path.req]
+    [path.member] -> [fs.path.member]
+    [path.construct] -> [fs.path.construct]
+    [path.assign] -> [fs.path.assign]
+    [path.append] -> [fs.path.append]
+    [path.concat] -> [fs.path.concat]
+    [path.modifiers] -> [fs.path.modifiers]
+    [path.native.obs] -> [fs.path.native.obs]
+    [path.generic.obs] -> [fs.path.generic.obs]
+    [path.compare] -> [fs.path.compare]
+    [path.decompose] -> [fs.path.decompose]
+    [path.query] -> [fs.path.query]
+    [path.gen] -> [fs.path.gen]
+    [path.itr] -> [fs.path.itr]
+    [path.non-member] -> [fs.path.nonmember]
+    [path.io] -> [fs.path.io]
+    [path.factory] -> [fs.path.factory]
+    [class.filesystem_error] -> [fs.class.filesystem_error]
+    [enum.path.format] -> [fs.enum.path.format]
+    [enum.file_type] -> [fs.enum.file_type]
+    [enum.copy_options] -> [fs.enum.copy.opts]
+    [enum.perms] -> [fs.enum.perms]
+    [enum.perm_options] -> [fs.enum.perm.opts]
+    [enum.directory_options] -> [fs.enum.dir.opts]
+    [class.file_status] -> [fs.class.file_status]
+    [file_status.cons] -> [fs.file_status.cons]
+    [file_status.obs] -> [fs.file_status.obs]
+    [file_status.mods] -> [fs.file_status.mods]
+    [class.directory_entry] -> [fs.class.directory_entry]
+    [directory_entry.cons] -> [fs.dir.entry.cons]
+    [directory_entry.mods] -> [fs.dir.entry.mods]
+    [directory_entry.obs] -> [fs.dir.entry.obs]
+    [class.directory_iterator] -> [fs.class.directory_iterator]
+    [directory_iterator.members] -> [fs.dir.itr.members]
+    [directory_iterator.nonmembers] -> [fs.dir.itr.nonmembers]
+    [class.rec.dir.itr] -> [fs.class.rec.dir.itr]
+    [rec.dir.itr.members] -> [fs.rec.dir.itr.members]
+    [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers]
+
+commit ad33212fded427f1e0b4e57c53c9e9215318b223
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Mar 16 11:21:05 2017 -0400
+
+    [any.modifiers] fix emplace return type for 'any' (#1545)
+
+    LWG issue 2857 was applied verbatim, without noticing
+    that 'ValueType' had been previously changed to 'T'.
+    This makes things consistent by choosing 'T' as the
+    simpler form, more consistent with 'optional' and
+    'variant'.
+
+commit 09e4674b0b6ab2f74bfe5a14120edea874115779
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 28 07:27:01 2017 +0100
+
+    [expr.prim.lambda] Move syntactic restriction on decl-specifier-seq to the front.
+
+    Per CWG guidance.
+
+commit 763a3fda5cec74d17371ddf4957f1f522331ebb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 30 19:17:52 2016 +0100
+
+    [expr.prim.lambda] Split specification of lambda expressions into subsections.
+
+    Fixes #1155.
+
+commit 8139f2f9ec81cf4b8c24640f968880241dd23231
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 19:51:44 2016 +0000
+
+    Move specification of deprecated headers to Annex D
+
+commit c9354b33e1de8e0cf6dc42a73c733e1d8a34e7e0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 18:29:49 2017 -0700
+
+    Update value of __cplusplus to 201703L.
+
+    Fixes #1513 and NB CA 15 and US 83 (C++17 CD).
+
+commit 8baa18cbbf33a9b73711638b13a4960e15179c6d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 18:29:13 2017 -0700
+
+    Add acknowledgement of ECMAScript trademark.
+
+    Fixes NB GB 10 (C++17 CD).
+
+commit 4d53b8b250751aae7768955f75eb7f27db08d83e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 12:55:55 2017 -0700
+
+    Editorial fixes for P0317R1.
+
+    [directory_entry.mods] Improve singular/plural, add commas.
+
+    [class.directory_iterator] Reorder words to more closely align xref with
+    the term for which it is a reference, add comma.
+
+commit dd42ed5d6e04e623992e0464e49323a2b6a1f518
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Mar 12 14:34:57 2017 -0700
+
+    [atomics.flag] Replace "shall be" with "is" when describing properties
+    of the implementation, for consistency with changes made by P0558R1.
+
+commit 49caa2b829256f8198ed649ca3f5057bde96a2c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 5 09:19:33 2017 -1000
+
+    [func.search] Add missing period
+
+commit 4f0891849e4799367174cc8783a3d88b6ff6b95a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Mar 3 02:36:27 2017 +0000
+
+    [meta.trans] replace "shall name" with "names" in traits tables
+
+commit 42c6d5cc8ed83ba4b48b8b94d51b7a317d577a46
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 20 21:45:21 2016 +0100
+
+    [lib] For showing complexity, use $N \log N$
+    and not $N \log(N)$ or other variants.
+
+    Partially addresses #1088.
+
+commit 42c5a2ce36d7403ca37cb8b038aa37065c353ba4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 20 23:45:26 2016 +0100
+
+    [intro.refs] Add normative references to LIA-1 and IEEE 754.
+
+    Fixes #237.
+
+commit bdff8687ccb470564400597403d484ad02890f24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 10 21:25:42 2017 +0100
+
+    [any] Use 'contained value' consistently.
+
+    This harmonizes the use of 'constained value' across
+    optional, variant, and any, with appropriate index
+    entries.
+
+    Fixes #1401.
+
+commit 6a5edb752b88c448dce4cba528de307d79966b9e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 9 21:42:49 2017 +0100
+
+    Harmonize punctuation for 'ill-formed, no diagnostic required'
+
+    Fixes #1450.
+
+commit 40f3fb37986ecff07567cc4601fac334fee8aff9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 15:35:43 2017 +0100
+
+    [basic.types] Remove excessive references to [basic.type.qualifier].
+
+    Fixes #1419.
+
+commit ee930ef3ee97f244d278ac3f762ec5f167dc005a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 2 02:20:48 2017 +0000
+
+    [rand.dist.bern.negbin] Fix index for k member
+
+commit bbcf0ea60c63d741bc51818633c70df2690e99b4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 1 13:34:52 2017 -1000
+
+    Add a note to the definition of literal type to indicate that it is not
+    a guarantee that such an object can be created in a constant expression.
+
+    Wording from John Spicer / CWG.
+
+    Addresses NB GB 68 (C++17 CD).
+
+commit be54f2e8e12c54071692ef3ebd6e49f6e3255a27
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Tue Feb 28 19:17:32 2017 +0100
+
+    [diff.decl] Fix typo (#1494)
+
+commit 2f6aff7e71cc33243671d1e501911d331af61fa3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 27 16:23:46 2017 -1000
+
+    [basic.stc] Fix introductory sentence on dynamic storage duration to
+    match later more-normative rule: it applies to objects, not storage.
+
+    Fixes NB JP 3 (C++17 CD).
+
+commit ec4ca6fc07907ea817152970c45d4c04c86d3c5c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 27 11:30:27 2017 -0800
+
+    [intro] Promote "Scope", "Normative references", "Terms and definitions"
+    to top-level clauses per ISO directives.
+
+    Modify \definition macro so we can more easily have definitions at
+    different depths in different lists.
+
+commit fe6c8bda60fbca2cd3a488650988ce0a7df20d03
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Feb 24 12:09:31 2017 +0100
+
+    [localization, diff] Remove superfluous 'return 0;' from 'main' in examples. (#1482)
+
+commit 17e28024d81e366a6d1044fa29a0cd1bdf10f77f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 23 12:32:58 2017 +0100
+
+    [meta.unary.prop, meta.trans.other] Omit unhelpful second argument in static_asserts. (#1479)
+
+commit 33f16cb3417ad21949769d82cae36c1b653e4519
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 23 01:47:09 2017 +0100
+
+    [dcl.attr.nodiscard] Clarify example with reference return type. (#1471)
+
+    Add rationale why a warning is not encouraged for this case.
+
+    Fixes #1470.
+
+commit 7cd42666e143e19bdaf9e62211066cab255fb99f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 23 01:25:26 2017 +0100
+
+    [expr.mptr.oper] Use defined term 'null member pointer value'. (#1434)
+
+commit 5bc5cbae28d9e741ebc7df996f1f0d230ac4087e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Feb 21 00:16:14 2017 +0100
+
+    [rand.req.{eng,dist}] Replace square brackets around reference with regular parentheses. (#1481)
+
+commit 44f489bba7c7595077043c7360cf7ff329eeb090
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 19 15:41:48 2017 +0100
+
+    [except.spec] Add missing 'an'. (#1478)
+
+commit 16938d84892051f5c9e2fe4afca578fc57b1c4f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Feb 18 19:21:13 2017 +0000
+
+    [support.runtime] Remove extraneous and misleading parentheses from names of functions and macros
+
+commit d2fe52eaaf53b6843ab6fe152a2a05e5a7da06fc
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 16 20:54:49 2017 +0100
+
+    [alg.min.max] Enlarge lfloor/rfloor delimiters. (#1455)
+
+commit 7e5537d1e9c7a6d63c9877cf5babde4ddf14807c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Feb 15 15:38:19 2017 +0100
+
+    Parenthesize some \refs. (#1436)
+
+commit 473966e60653e8e2bc8ed154d8b18a3736f97088
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 9 12:14:12 2017 +0100
+
+    [unord.req] Insert hint is 'p', not 'q' (#1440)
+
+    LWG 2540 changed the hint for insert from 'q'
+    (a valid and dereferenceable iterator) to 'p'
+    (a valid, but not necessarily dereferenceable iterator),
+    but neglected to adjust the description text.
+
+    Fixes #1423.
+
+commit 90c486f80612c3a7fd26ee408631991814f7b81c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 17:21:31 2017 +0100
+
+    [any.assign] Rename T to VT. (#1448)
+
+    These renames were overlooked in commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274.
+
+    Fixes #1443.
+
diff --git a/papers/n4661.md b/papers/n4661.md new file mode 100644 index 0000000000..a8331e1952 --- /dev/null +++ b/papers/n4661.md @@ -0,0 +1,825 @@ +# N4661 Editors' Report -- Programming Languages -- C++ + +2017-03-20 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +the members of the editing committee for the C++17 DIS, namely +Marshall Clow, +Mike Miller, +Ville Voutilainen, +and +Jeffrey Yasskin +for their review of the correctness of the working paper +as modified by the motions from the Kona 2017 meeting. + +Special thanks also to +Jonathan Wakely +and +Alisdair Meredith +for performing edits and editorial review for several of the motions applied since N4640, +and to +Jens Maurer +for performing many of the editorial fixes since N4640. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4659](http://wg21.link/n4659) is the current working draft. It replaces [N4640](http://wg21.link/n4640). + * [N4660](http://wg21.link/n4660) is the C++17 DIS. + * N4661 is this Editors' Report. + +The contents of N4659 and N4660 are identical except for the cover sheet and +page headings. + +## Motions incorporated into working draft and C++17 DIS + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0575r1) for 5 issues in "ready" status applied: + + * [1677](http://wg21.link/cwg1677) Constant initialization via aggregate initialization + * [1860](http://wg21.link/cwg1860) What is a "direct member?" + * [2174](http://wg21.link/cwg2174) Unclear rules for friend definitions in templates + * [2205](http://wg21.link/cwg2205) Restrictions on use of alignas + * [2218](http://wg21.link/cwg2218) Ambiguity and namespace aliases + +**The other 7 issues in "ready" status from P0575R1 were applied by CWG Motion 3** + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0576r1) for 5 issues in "tentatively ready" status applied: + + * [2201](http://wg21.link/cwg2201) Cv-qualification of array types + * [2206](http://wg21.link/cwg2206) Composite type of object and function pointers + * [2214](http://wg21.link/cwg2214) Missing requirement on representation of integer values + * [2220](http://wg21.link/cwg2220) Hiding index variable in range-based `for` + * [2224](http://wg21.link/cwg2224) Member subobjects and base-class casts + * [2259](http://wg21.link/cwg2259) Unclear context describing ambiguity + * [2262](http://wg21.link/cwg2262) Attributes for *asm-definition* + +CWG motion 3: [Core issue resolutions](http://wg21.link/p0622r0) for 12 issues in "ready" and "tentatively ready" status applied, resolving 13 issues: + + * [426](http://wg21.link/cwg426) Identically-named variables, one internally and one externally linked, allowed? + * [727](http://wg21.link/cwg727) In-class explicit specializations + * [1622](http://wg21.link/cwg1622) Empty aggregate initializer for union (no changes, resolved by 2272) + * [1710](http://wg21.link/cwg1710) Missing `template` keyword in *class-or-decltype* + * [2196](http://wg21.link/cwg2196) Zero-initialization with virtual base classes + * [2198](http://wg21.link/cwg2198) Linkage of enumerators + * [2211](http://wg21.link/cwg2211) Hiding by lambda captures and parameters + * [2247](http://wg21.link/cwg2247) Lambda capture and variable argument list + * [2248](http://wg21.link/cwg2248) Problems with sized delete + * [2251](http://wg21.link/cwg2251) Unreachable enumeration list-initialization + * [2268](http://wg21.link/cwg2268) Unions with mutable members in constant expressions revisited + * [2272](http://wg21.link/cwg2272) Implicit initialization of aggregate members of reference type + * [2276](http://wg21.link/cwg2276) Dependent `noexcept` and function type-dependence + +CWG motion 4: [P0612R0 "NB comment CH 2: volatile"](http://wg21.link/p0612r0), resolving 1 NB comment: + + * CH 2: Clarify whether volatile semantics require volatile objects or merely volatile-qualified glvalues + +CWG motion 5: [P0613R0 "NB comment GB15: Resolution of Core Issue 2011"](http://wg21.link/p0613r0), resolving 1 NB comment and 1 issue: + + * GB 15, [2011](http://wg21.link/cwg2011) Unclear effect of reference capture of reference + +CWG motion 6: [P0298R3 "A `byte` type definition"](http://wg21.link/p0298r3), resolving 3 NB comments: + + * CA 11, US 72: Adopt [P0257R1 "A `byte` type for increased type safety"](http://wg21.link/p0257r1) with modifications + * US 22: Adopt [P0298R1 "A `byte` type definition"](http://wg21.link/p0298r1) + +CWG motion 7: [P0615R0 "Renaming for structured bindings"](http://wg21.link/p0615r0) + +CWG motion 8: [P0620R0 "Drafting for class template argument deduction issues"](http://wg21.link/p0620r0), resolving 3 NB comments: + + * US 94, GB 13, FI 21: Support class template argument deduction in `T{x1, x2, ...}` syntax + +CWG motion 9: [P0270R3 "Removing C dependencies from signal handler wording"](http://wg21.link/p0270r3) **with changes, see below**, resolving 1 NB comment: + + * CA 1: Adopt [P0270R1 "Removing C dependencies from signal handler wording"](http://wg21.link/p0270r1) + +CWG motion 10: [P0250R3 "Wording improvements for initialization and thread ids"](http://wg21.link/p0250r3), resolving 2 issues in "concurrency" status: + + * [1784](http://wg21.link/cwg1784) Concurrent execution during static local initialization + * [2046](http://wg21.link/cwg2046) Incomplete thread specifications + +CWG motion 11a applies to the Modules TS. + +CWG motion 11b was not approved. + +### Library working group motions + +#### Issue resolutions + +LWG motion 1 applies to the Coroutines TS. + +LWG motion 2: [Library issue resolutions](http://wg21.link/p0165r4) for 22 issues in "Ready" and "Tentatively Ready" status applied, resolving 23 issues: + + * [2260](http://wg21.link/lwg2260) Missing requirement for `Allocator::pointer` + * [2768](http://wg21.link/lwg2768) `any_cast` and move semantics (no changes, resolved by 2769) + * [2769](http://wg21.link/lwg2769) Redundant `const` in the return type of `any_cast(const any&)` + * [2781](http://wg21.link/lwg2781) Contradictory requirements for `std::function` and `std::reference_wrapper` + * [2782](http://wg21.link/lwg2782) `scoped_allocator_adaptor` constructors must be constrained + * [2784](http://wg21.link/lwg2784) Resolution to [LWG 2484](http://wg21.link/lwg2484) is missing "otherwise, no effects" and is hard to parse + * [2785](http://wg21.link/lwg2785) `quoted` should work with `basic_string_view` + * [2786](http://wg21.link/lwg2786) Annex C should mention `shared_ptr` changes for array support + * [2787](http://wg21.link/lwg2787) [file_status.cons] doesn't match class definition + * [2789](http://wg21.link/lwg2789) Equivalence of contained objects + * [2794](http://wg21.link/lwg2794) Missing requirements for allocator pointers + * [2795](http://wg21.link/lwg2795) [global.functions] provides incorrect example of ADL use + * [2804](http://wg21.link/lwg2804) Unconditional `constexpr` default constructor for `istream_iterator` + * [2824](http://wg21.link/lwg2824) `list::sort` should say that the order of elements is unspecified if an exception is thrown + * [2826](http://wg21.link/lwg2826) `string_view` iterators use old wording + * [2834](http://wg21.link/lwg2834) Resolution to [LWG 2223](http://wg21.link/lwg2223) is missing wording about end iterators + * [2835](http://wg21.link/lwg2835) Resolution to [LWG 2536](http://wg21.link/lwg2536) seems to misspecify `` + * [2837](http://wg21.link/lwg2837) `gcd` and `lcm` should support a wider range of input values + * [2838](http://wg21.link/lwg2838) `is_literal_type` specification needs a little cleanup + * [2842](http://wg21.link/lwg2842) `in_place_t` check for `optional::optional(U&&)` should decay `U` + * [2850](http://wg21.link/lwg2850) `std::function` move constructor does unnecessary work + * [2853](http://wg21.link/lwg2853) Possible inconsistency in specification of `erase` in [vector.modifiers] + * [2855](http://wg21.link/lwg2855) `std::throw_with_nested("string_literal")` + +**Resolution of [2812](http://wg21.link/lwg2812) "Range access is available with ``" not applied, as this issue had already been resolved editorially** + +LWG motion 3: [Library issue resolutions](http://wg21.link/p0610r0) for 3 issues in "Review" status applied: + + * [2676](http://wg21.link/lwg2676) Provide `filesystem::path` overloads for "File-based streams" + * [2790](http://wg21.link/lwg2790) Missing specification of `istreambuf_iterator::operator->` + * [2796](http://wg21.link/lwg2796) `tuple` should be a literal type + +#### Filesystem + +LWG motion 4: [P0317R1 "Directory entry caching for filesystem"](http://wg21.link/p0317r1) **with changes, see below** + +LWG motion 5: [P0492R2 "Proposed resolution of C++17 National Body comments for filesystems"](http://wg21.link/p0492r2), resolving 31 NB comments and 2 issues: + + * US 32: Meaning of [fs.conform.9945] unclear + * US 33: Definition of "canonical path" problematic + * US 34: Are there attributes of a file that are not an aspect of the file system? + * US 36: Symbolic links themselves are attached to a directory via (hard) links + * US 37: The term "redundant current directory (*dot*) elements" is not defined + * US 43: Concerns about encoded character types + * US 44, [2798](http://wg21.link/lwg2798): Definition of `path` in terms of a string requires leaky abstraction + * US 45: Generic format portability compromised by unspecified *root-name* (no changes, resolved by US 73, CA 2) + * US 46: *filename* can be empty so productions for *relative-path* are redundant + * US 47: `.` and `..` already match the *name* production + * US 48: Multiple separators are often meaningful in a *root-name* + * US 51: Failing to add `/` when appending empty string prevents useful applications (no changes, resolved by US 74, CA 3) + * US 52, [2665](http://wg21.link/lwg2665): `remove_filename` postcondition is not by itself a definition + * US 53: `remove_filename`'s name does not correspond to its behavior (no changes, resolved by US 52, US 60) + * US 54: `remove_filename` is broken + * US 55: `replace_extension`'s use of `path` as parameter is inappropriate + * US 58: `parent_path` behavior for root paths is useless (no changes, resolved by US 77, CA 6) + * US 60: `path("/foo/").filename() == path(".")` is surprising + * US 61: Leading dots in `filename` should not begin an extension (no changes, resolved by US 74, CA 3) + * US 62: It is important that `stem() + extension() == filename()` (no changes, resolved by US 74, CA 3) + * US 63: `lexically_normal` inconsistently treats trailing `/` but not `/..` as directory (no changes, resolved by US 37, US 74, CA 3) + * US 73, CA 2: *root-name* is effectively implementation defined + * US 74, CA 3: The term "pathname" is ambiguous in some contexts + * US 77, CA 6: `operator/` and other `append`s not useful if arg has *root-name* + * US 78, CA 7: Member `absolute` in [fs.op.absolute] is overspecified for non-POSIX-like O/S + * Late 36: `permissions` `error_code` overload should be `noexcept` (no changes, resolved by Late 37) + * Late 37: `permissions` actions should be separate parameter + +LWG motion 6: [P0430R2 "File system library on non-POSIX-like operating systems"](http://wg21.link/p0430r2), resolving 6 NB comments: + + * US 75, CA 4: Extra flag in `path` constructors is needed + * US 76, CA 5: *root-name* definition is over-specified. + * US 79, CA 8: Some operation functions are overspecified for implementation-defined file types + +#### Parallel algorithms + +LWG motion 7: [P0452R1 "Unifying `` parallel algorithms"](http://wg21.link/p0452r1), partially resolving 2 NB comments: + + * US 161: `inner_product` should use *`GENERALIZED_SUM`* + * US 184: `inner_product` should not have `ExecutionPolicy` overload + +LWG motion 8: [P0518R1 "Allowing copies as arguments to function objects given to parallel algorithms"](http://wg21.link/p0518r1), resolving 1 NB comment: + + * CH 11: Allow parallel algorithms to make copies of their arguments + +LWG motion 9: [P0523R1 "Complexity of parallel algorithms"](http://wg21.link/p0523r1), partially resolving 1 NB comment: + + * CH 10: Relax complexity specifications for parallel algorithms + +LWG motion 10: [P0574R1 "Algorithm complexity constraints and parallel overloads"](http://wg21.link/p0574r1), partially resolving 1 NB comment: + + * CH 10: Relax complexity specifications for parallel algorithms + +LWG motion 11: [P0467R2 "Iterator concerns for parallel algorithms"](http://wg21.link/p0467r2), partially resolving 2 NB comments: + + * US 156: Relax iterator requirements for parallel algorithms + * US 162: Relax parallel `adjacent_difference` specification to permit parallelization + +LWG motion 12: [P0623R0 "Final C++17 parallel algorithms fixes"](http://wg21.link/p0623r0), partially resolving 3 NB comments: + + * US 161: `inner_product` should use *`GENERALIZED_SUM`* + * US 162: Relax parallel `adjacent_difference` specification to permit parallelization + * US 184: `inner_product` should not have `ExecutionPolicy` overload + +#### NB response papers + +LWG motion 13: [P0604R0 "Resolving GB 55, US 84, US 85, US 86"](http://wg21.link/p0604r0), resolving 4 NB comments: + + * GB 55, US 85: Fix `is_callable` and `result_of` to not use a function type as their interface + * US 84: More clearly distinguish `*INVOKE(f, t1, t2, ..., tN)*` and `*INVOKE(f, t1, t2, ..., tN, R)*` + * US 86: Rename `is_callable` to `is_invocable` + +LWG motion 14: [P0607R0 "`inline` variables for the standard library"](http://wg21.link/p0607r0), resolving 2 NB comments: + + * FI 9, GB28: Use `inline` variables for library tag types + +LWG motion 15: [P0618R0 "Deprecating ``"](http://wg21.link/p0618r0), resolving 3 NB comments: + + * GB 57: Deprecate `` + * US 64, CA 9: Preserve references to UCS2 + +LWG motion 16: **Revert [P0181R1 "Ordered By Default"](http://wg21.link/p0181r1)**, applied by 2016-06 LWG Motion 21, resolving 1 NB comment: + + * FI 18: Revert addition of `default_order` + +LWG motion 17: [P0156R2 "Variadic lock guard"](http://wg21.link/p0156r2), resolving 2 NB comments: + + * FI 8, GB 61: Revert making `lock_guard` variadic + +LWG motion 18: [P0599R1 "`noexcept` for `hash` functions"](http://wg21.link/p0599r1), resolving 1 NB comment: + + * US 140: Some or all `hash` specializations should be `noexcept` + +LWG motion 19: [P0433R2 "Integrating template deduction for class templates into the standard library"](http://wg21.link/p0433r2), resolving 2 NB comments and 3 issues: + + * US 7, US 19 (remaining parts after P0512R0), US 147, US 148, US 150: Provide suitable deduction guides for the standard library + +**Despite the claims of this paper and the wording of Motion 19, +this paper is unrelated to US 14** + +#### NB issue resolutions + +LWG motion 20: [Library issue resolutions](http://wg21.link/p0625r0) for 23 issues in "Immediate" status applied, resolving 20 NB comments: + + * CH 7, [2904](http://wg21.link/lwg2904): Make `variant` move-assignment more exception safe + * GB 36, [2866](http://wg21.link/lwg2866): Incorrect derived classes constraints + * GB 49, [2806](http://wg21.link/lwg2806): Base class of `bad_optional_access` + * GB 53, [2807](http://wg21.link/lwg2807): `std::invoke` should use `std::is_nothrow_callable` + * GB 54, [2868](http://wg21.link/lwg2868): Missing specification of `bad_any_cast::what()` + * US 107, [2872](http://wg21.link/lwg2872): Add definition for "direct-non-list-initialization" + * US 111, [2890](http://wg21.link/lwg2890): The definition of "object state" applies only to class types + * US 111, [2900](http://wg21.link/lwg2900): The copy and move constructors of `optional` are not `constexpr` + * US 118, [2903](http://wg21.link/lwg2903): The form of initialization for the emplace-constructors is not specified + * US 122, [2801](http://wg21.link/lwg2801): Default-constructibility of `unique_ptr` + * US 123, [2905](http://wg21.link/lwg2905): `is_constructible_v | P | D const &>` should be `false` when `D` is not copy constructible + * US 124, [2873](http://wg21.link/lwg2873): Add `noexcept` to several `shared_ptr` related functions + * US 125, [2874](http://wg21.link/lwg2874): Constructor `shared_ptr::shared_ptr(Y*)` should be constrained + * US 126, [2875](http://wg21.link/lwg2875): `shared_ptr::shared_ptr(Y* | D | […])` constructors should be constrained + * US 127, [2802](http://wg21.link/lwg2802): `shared_ptr` constructor requirements for a deleter + * US 129, [2876](http://wg21.link/lwg2876): `shared_ptr::shared_ptr(const weak_ptr&)` constructor should be constrained + * US 135, [2908](http://wg21.link/lwg2908): The less-than operator for shared pointers could do more + * US 145, [2861](http://wg21.link/lwg2861): `basic_string` should require that `charT` match `traits::char_type` + * US 153, [2878](http://wg21.link/lwg2878): Missing DefaultConstructible requirement for `istream_iterator` default constructor + * US 165, [2921](http://wg21.link/lwg2921): `packaged_task` and type-erased allocators + * [2788](http://wg21.link/lwg2788): `basic_string` range mutators unintentionally require a default constructible allocator + * [2857](http://wg21.link/lwg2857): `{variant,optional,any}::emplace` should return the constructed value + * [2934](http://wg21.link/lwg2934): `optional` doesn't compare with `T` + +**Note: the resolutions of issues 2894 and 2911 in P0625R0 are not included in this motion** + +LWG motion 20a was not approved. + +LWG motion 20b: [Library issue resolution](http://wg21.link/p0625r0) for 1 issue in "Immediate" status applied, resolving 1 NB comment: + + * US 143, [2911](http://wg21.link/lwg2911): An `is_aggregate_type` trait is needed + +#### Non-NB-comment papers + +LWG motion 21: [P0558R1 "Resolving `atomic` named base class inconsistencies"](http://wg21.link/p0558r1) + +LWG motion 22: [P0548R1 "`common_type` and `duration`"](http://wg21.link/p0548r1) + +LWG motion 23 applies to the Ranges TS. + +## Notable editorial changes + +### Motions + + * CWG 6: In application of P0298R3, updated introductory sentence of [cstddef.syn] + to avoid claiming that `std::byte` is part of ISO C's `` header. + + * CWG 9: Change to [csignal.syn] was not applied, because the desired normative + effect had already been accomplished by [P0175R1](http://wg21.link/p0175r1), + which was applied at the previous meeting and removed the baseline text for + this change. The effect of the merge is that `std::signal` is *not* required + to itself have C language linkage (but its parameter and returned function + pointer types are). Also added subclause to house description of signal + handlers, rather than including it in the `` header synopsis. + + * LWG 4: The normative description of `directory_entry::is_directory` is + specified in terms of a non-existent `file_status` member, and either the + `status` or `symlink_status` members could have been intended. After + [consulting with LWG](http://lists.isocpp.org/lib/2017/03/2262.php), + this usage of `file_status` has been replaced by `status`. + +### NB comments + + * `__cplusplus` macro value updated from `201402L` to `201703L`, resolving + NB comments CA 15 and US 83. + + * Added acknowledgement of ECMAScript trademark, resolving NB comment GB 10. + + * Added normative references to LIA-1 and IEEE 754. + + * Added note to definition of literal type, resolving NB comment GB 68. + + * Made introductory sentence of [basic.stc] consistent with later normative + wording, resolving NB comment JP 3, as directed by CWG. + +### ISO Directives + + * Promoted "Scope", "Normative references", and "Terms and definitions" to + top-level Clauses as required by ISO Directives. + + * Updated introductory text of "Normative references" and "Terms and definitions" + to match those specified by ISO Directives. + +### Content rearrangement + + * [fs.path.generic]: rearranged *pathname* grammar to avoid long paragraphs of + text in descriptive elements and refactored to fix ambiguities in the + grammar, after consultation with LWG. + + * [expr.prim.lambda]: split out subclauses for the closure type and captures; + reviewed by CWG at Kona 2017. + + * Move specification of deprecated standard library headers into Annex D, + after consultation with LWG. + +### Stable name changes + + * A "Cross references from ISO C++ 2014" section has been added, listing all + stable names from C++ 2014 that do not appear within the C++ 2017 standard, + and where the corresponding text can be found (if it still exists). + + * Systematic review and cleanup of filesystem stable names: + [class.path] -> [fs.class.path] + [path.generic] -> [fs.path.generic] + [path.cvt] -> [fs.path.cvt] + [path.fmt.cvt] -> [fs.path.fmt.cvt] + [path.type.cvt] -> [fs.path.type.cvt] + [path.req] -> [fs.path.req] + [path.member] -> [fs.path.member] + [path.construct] -> [fs.path.construct] + [path.assign] -> [fs.path.assign] + [path.append] -> [fs.path.append] + [path.concat] -> [fs.path.concat] + [path.modifiers] -> [fs.path.modifiers] + [path.native.obs] -> [fs.path.native.obs] + [path.generic.obs] -> [fs.path.generic.obs] + [path.compare] -> [fs.path.compare] + [path.decompose] -> [fs.path.decompose] + [path.query] -> [fs.path.query] + [path.gen] -> [fs.path.gen] + [path.itr] -> [fs.path.itr] + [path.non-member] -> [fs.path.nonmember] + [path.io] -> [fs.path.io] + [path.factory] -> [fs.path.factory] + [class.filesystem\_error] -> [fs.class.filesystem\_error] + [enum.path.format] -> [fs.enum.path.format] + [enum.file\_type] -> [fs.enum.file\_type] + [enum.copy\_options] -> [fs.enum.copy.opts] + [enum.perms] -> [fs.enum.perms] + [enum.perm\_options] -> [fs.enum.perm.opts] + [enum.directory\_options] -> [fs.enum.dir.opts] + [class.file\_status] -> [fs.class.file\_status] + [file\_status.cons] -> [fs.file\_status.cons] + [file\_status.obs] -> [fs.file\_status.obs] + [file\_status.mods] -> [fs.file\_status.mods] + [class.directory\_entry] -> [fs.class.directory\_entry] + [directory\_entry.cons] -> [fs.dir.entry.cons] + [directory\_entry.mods] -> [fs.dir.entry.mods] + [directory\_entry.obs] -> [fs.dir.entry.obs] + [class.directory\_iterator] -> [fs.class.directory\_iterator] + [directory\_iterator.members] -> [fs.dir.itr.members] + [directory\_iterator.nonmembers] -> [fs.dir.itr.nonmembers] + [class.rec.dir.itr] -> [fs.class.rec.dir.itr] + [rec.dir.itr.members] -> [fs.rec.dir.itr.members] + [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers] + + * [istreambuf.iterator] 5 subclauses + [istreambuf.iterator::equal], + [istreambuf.iterator::op!=], + [istreambuf.iterator::op\*], + [istreambuf.iterator::op++], + [istreambuf.iterator::op==] + merged into a single [istreambuf.iterator.ops] comprising half a page of text; + + * Several subclauses with stable names containing `::` have been renamed to + instead use `.` as the component separator. + +## Minor editorial fixes + +A log of editorial fixes made since N4640 is below. This list excludes changes +that do not affect the body text or only affect whitespace or typeface. For a +complete list including such changes (or for the actual deltas applied by these +changes), consult the [draft sources on github](https://github.com/cplusplus/draft/compare/n4640...n4659). + + commit dbf3efe18813054c95abae388c53bf30e96e7e83 + Author: Richard Smith + Date: Mon Mar 20 15:19:47 2017 -0700 + + [intro.refs], [intro.defs] Update introductory text to match latest ISO + Directives. + + commit 32825151765e214d79103a137aa29a9a4357687f + Author: Richard Smith + Date: Mon Mar 20 15:00:51 2017 -0700 + + Replace "this International Standard" with "this document" in some + places where it is a clear improvement. + + The 7th Edition of the ISO Directives no longer require us to use + "this International Standard" when the document refers to itself. We + retain that phrasing when the reference is to the abstract notion of + the specification as opposed to the text embodying it. + + This is a step towards addressing #1389. + + commit 1798a9b6795d6ee92bf093e2a6256c34212552b1 + Author: Richard Smith + Date: Mon Mar 20 14:14:22 2017 -0700 + + [fs.path.generic] Refactor generic pathname grammar to remove redundancy and ambiguity. + + commit 660d97e40353337b0b6b533903ab16e330855a77 + Author: Eelis van der Weegen + Date: Sat Aug 6 18:02:50 2016 +0200 + + [depr.func.adaptor.typedefs] Clarify that reference_wrapper does not define argument_type for non-nullary member function pointer types. + + commit 95cbc03c20f20d98a53a3e696df6003ec27abc42 + Author: Jens Maurer + Date: Wed Feb 8 16:35:25 2017 +0100 + + [istreambuf.iterator] Join subsections for operations descriptions. + + There was one subsection for every operator, yet everything + fits on half a page. + + Fixes #1429, #1449. + + commit d2b6fb6eefc3c28eb448352cd6d8b0d08e860a66 + Author: Jonathan Wakely + Date: Thu Mar 16 21:27:11 2017 +0000 + + [containers] Rephrase deduction guide constraints + + Replace "is called with" wording that doesn't apply to deduction guides. + + Move rules about qualifying as input iterators or allocators to + [container.requirements.general]. + + commit a7f52d1904e5a6d2d407eb4145ba54552d0b3e69 + Author: Richard Smith + Date: Mon Mar 20 00:07:04 2017 -0700 + + [fs.path.generic] Move descriptions of grammar elements out of the + grammar and into separate paragraphs, and format path grammar as we + format the language grammar. + + Also rephrase description of root-name to use the defined term + "implementation-defined" directly rather than separating it into + "implementations [...] define". + + commit 04a9e5d759b4fea810ed029dd6b6a0d5ebfd224a + Author: Jens Maurer + Date: Fri Feb 10 22:46:20 2017 +0100 + + [fs.op.copy], [fs.op.copy_file] Rephrase requirements on copy_options. + + Use bitmask 'element' phrasing for restrictions on copy_options. + + Fixes #1445. + + commit df9a809a36c34acc0870c5d7869e7549574e1437 + Author: Jens Maurer + Date: Sat Mar 18 23:08:32 2017 +0100 + + [partial.sort] Remove 'It takes' from complexity specification. + + Partially addresses #1088. + + commit 5cf60394dbe171ec16bfbba1459772e40b9cf6e1 + Author: Thomas Köppe + Date: Sat Mar 18 21:21:14 2017 +0000 + + [temp.class.spec.mfunc] Add missing comment to example + + commit cdd6dda21e3273ea63b733c3cfb3b630bb1847eb + Author: Richard Smith + Date: Thu Mar 16 15:37:17 2017 -0700 + + [xref] Add glossary of cross-references between C++14 section labels and + C++17 section labels. + + Fixes #1547. + + commit 88c20950fac6915844143bb73129e2eb1b41d17d + Author: Jonathan Wakely + Date: Thu Mar 16 02:51:38 2017 +0000 + + [filesystem] Shorten stable names and add "fs." prefixes + + [class.path] -> [fs.class.path] + [path.generic] -> [fs.path.generic] + [path.cvt] -> [fs.path.cvt] + [path.fmt.cvt] -> [fs.path.fmt.cvt] + [path.type.cvt] -> [fs.path.type.cvt] + [path.req] -> [fs.path.req] + [path.member] -> [fs.path.member] + [path.construct] -> [fs.path.construct] + [path.assign] -> [fs.path.assign] + [path.append] -> [fs.path.append] + [path.concat] -> [fs.path.concat] + [path.modifiers] -> [fs.path.modifiers] + [path.native.obs] -> [fs.path.native.obs] + [path.generic.obs] -> [fs.path.generic.obs] + [path.compare] -> [fs.path.compare] + [path.decompose] -> [fs.path.decompose] + [path.query] -> [fs.path.query] + [path.gen] -> [fs.path.gen] + [path.itr] -> [fs.path.itr] + [path.non-member] -> [fs.path.nonmember] + [path.io] -> [fs.path.io] + [path.factory] -> [fs.path.factory] + [class.filesystem_error] -> [fs.class.filesystem_error] + [enum.path.format] -> [fs.enum.path.format] + [enum.file_type] -> [fs.enum.file_type] + [enum.copy_options] -> [fs.enum.copy.opts] + [enum.perms] -> [fs.enum.perms] + [enum.perm_options] -> [fs.enum.perm.opts] + [enum.directory_options] -> [fs.enum.dir.opts] + [class.file_status] -> [fs.class.file_status] + [file_status.cons] -> [fs.file_status.cons] + [file_status.obs] -> [fs.file_status.obs] + [file_status.mods] -> [fs.file_status.mods] + [class.directory_entry] -> [fs.class.directory_entry] + [directory_entry.cons] -> [fs.dir.entry.cons] + [directory_entry.mods] -> [fs.dir.entry.mods] + [directory_entry.obs] -> [fs.dir.entry.obs] + [class.directory_iterator] -> [fs.class.directory_iterator] + [directory_iterator.members] -> [fs.dir.itr.members] + [directory_iterator.nonmembers] -> [fs.dir.itr.nonmembers] + [class.rec.dir.itr] -> [fs.class.rec.dir.itr] + [rec.dir.itr.members] -> [fs.rec.dir.itr.members] + [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers] + + commit ad33212fded427f1e0b4e57c53c9e9215318b223 + Author: Alisdair Meredith + Date: Thu Mar 16 11:21:05 2017 -0400 + + [any.modifiers] fix emplace return type for 'any' (#1545) + + LWG issue 2857 was applied verbatim, without noticing + that 'ValueType' had been previously changed to 'T'. + This makes things consistent by choosing 'T' as the + simpler form, more consistent with 'optional' and + 'variant'. + + commit 09e4674b0b6ab2f74bfe5a14120edea874115779 + Author: Jens Maurer + Date: Tue Feb 28 07:27:01 2017 +0100 + + [expr.prim.lambda] Move syntactic restriction on decl-specifier-seq to the front. + + Per CWG guidance. + + commit 763a3fda5cec74d17371ddf4957f1f522331ebb0 + Author: Jens Maurer + Date: Wed Nov 30 19:17:52 2016 +0100 + + [expr.prim.lambda] Split specification of lambda expressions into subsections. + + Fixes #1155. + + commit 8139f2f9ec81cf4b8c24640f968880241dd23231 + Author: Thomas Köppe + Date: Thu Nov 17 19:51:44 2016 +0000 + + Move specification of deprecated headers to Annex D + + commit c9354b33e1de8e0cf6dc42a73c733e1d8a34e7e0 + Author: Richard Smith + Date: Wed Mar 15 18:29:49 2017 -0700 + + Update value of __cplusplus to 201703L. + + Fixes #1513 and NB CA 15 and US 83 (C++17 CD). + + commit 8baa18cbbf33a9b73711638b13a4960e15179c6d + Author: Richard Smith + Date: Wed Mar 15 18:29:13 2017 -0700 + + Add acknowledgement of ECMAScript trademark. + + Fixes NB GB 10 (C++17 CD). + + commit 4d53b8b250751aae7768955f75eb7f27db08d83e + Author: Richard Smith + Date: Wed Mar 15 12:55:55 2017 -0700 + + Editorial fixes for P0317R1. + + [directory_entry.mods] Improve singular/plural, add commas. + + [class.directory_iterator] Reorder words to more closely align xref with + the term for which it is a reference, add comma. + + commit dd42ed5d6e04e623992e0464e49323a2b6a1f518 + Author: Richard Smith + Date: Sun Mar 12 14:34:57 2017 -0700 + + [atomics.flag] Replace "shall be" with "is" when describing properties + of the implementation, for consistency with changes made by P0558R1. + + commit 49caa2b829256f8198ed649ca3f5057bde96a2c7 + Author: Thomas Köppe + Date: Sun Mar 5 09:19:33 2017 -1000 + + [func.search] Add missing period + + commit 4f0891849e4799367174cc8783a3d88b6ff6b95a + Author: Jonathan Wakely + Date: Fri Mar 3 02:36:27 2017 +0000 + + [meta.trans] replace "shall name" with "names" in traits tables + + commit 42c6d5cc8ed83ba4b48b8b94d51b7a317d577a46 + Author: Jens Maurer + Date: Tue Dec 20 21:45:21 2016 +0100 + + [lib] For showing complexity, use $N \log N$ + and not $N \log(N)$ or other variants. + + Partially addresses #1088. + + commit 42c5a2ce36d7403ca37cb8b038aa37065c353ba4 + Author: Jens Maurer + Date: Tue Dec 20 23:45:26 2016 +0100 + + [intro.refs] Add normative references to LIA-1 and IEEE 754. + + Fixes #237. + + commit bdff8687ccb470564400597403d484ad02890f24 + Author: Jens Maurer + Date: Fri Feb 10 21:25:42 2017 +0100 + + [any] Use 'contained value' consistently. + + This harmonizes the use of 'constained value' across + optional, variant, and any, with appropriate index + entries. + + Fixes #1401. + + commit 6a5edb752b88c448dce4cba528de307d79966b9e + Author: Jens Maurer + Date: Thu Feb 9 21:42:49 2017 +0100 + + Harmonize punctuation for 'ill-formed, no diagnostic required' + + Fixes #1450. + + commit 40f3fb37986ecff07567cc4601fac334fee8aff9 + Author: Jens Maurer + Date: Wed Feb 8 15:35:43 2017 +0100 + + [basic.types] Remove excessive references to [basic.type.qualifier]. + + Fixes #1419. + + commit ee930ef3ee97f244d278ac3f762ec5f167dc005a + Author: Jonathan Wakely + Date: Thu Mar 2 02:20:48 2017 +0000 + + [rand.dist.bern.negbin] Fix index for k member + + commit bbcf0ea60c63d741bc51818633c70df2690e99b4 + Author: Richard Smith + Date: Wed Mar 1 13:34:52 2017 -1000 + + Add a note to the definition of literal type to indicate that it is not + a guarantee that such an object can be created in a constant expression. + + Wording from John Spicer / CWG. + + Addresses NB GB 68 (C++17 CD). + + commit be54f2e8e12c54071692ef3ebd6e49f6e3255a27 + Author: Jakub Wilk + Date: Tue Feb 28 19:17:32 2017 +0100 + + [diff.decl] Fix typo (#1494) + + commit 2f6aff7e71cc33243671d1e501911d331af61fa3 + Author: Richard Smith + Date: Mon Feb 27 16:23:46 2017 -1000 + + [basic.stc] Fix introductory sentence on dynamic storage duration to + match later more-normative rule: it applies to objects, not storage. + + Fixes NB JP 3 (C++17 CD). + + commit ec4ca6fc07907ea817152970c45d4c04c86d3c5c + Author: Richard Smith + Date: Mon Feb 27 11:30:27 2017 -0800 + + [intro] Promote "Scope", "Normative references", "Terms and definitions" + to top-level clauses per ISO directives. + + Modify \definition macro so we can more easily have definitions at + different depths in different lists. + + commit fe6c8bda60fbca2cd3a488650988ce0a7df20d03 + Author: Eelis + Date: Fri Feb 24 12:09:31 2017 +0100 + + [localization, diff] Remove superfluous 'return 0;' from 'main' in examples. (#1482) + + commit 17e28024d81e366a6d1044fa29a0cd1bdf10f77f + Author: Eelis + Date: Thu Feb 23 12:32:58 2017 +0100 + + [meta.unary.prop, meta.trans.other] Omit unhelpful second argument in static_asserts. (#1479) + + commit 33f16cb3417ad21949769d82cae36c1b653e4519 + Author: Jens Maurer + Date: Thu Feb 23 01:47:09 2017 +0100 + + [dcl.attr.nodiscard] Clarify example with reference return type. (#1471) + + Add rationale why a warning is not encouraged for this case. + + Fixes #1470. + + commit 7cd42666e143e19bdaf9e62211066cab255fb99f + Author: Eelis + Date: Thu Feb 23 01:25:26 2017 +0100 + + [expr.mptr.oper] Use defined term 'null member pointer value'. (#1434) + + commit 5bc5cbae28d9e741ebc7df996f1f0d230ac4087e + Author: Eelis + Date: Tue Feb 21 00:16:14 2017 +0100 + + [rand.req.{eng,dist}] Replace square brackets around reference with regular parentheses. (#1481) + + commit 44f489bba7c7595077043c7360cf7ff329eeb090 + Author: Eelis + Date: Sun Feb 19 15:41:48 2017 +0100 + + [except.spec] Add missing 'an'. (#1478) + + commit 16938d84892051f5c9e2fe4afca578fc57b1c4f3 + Author: Thomas Köppe + Date: Sat Feb 18 19:21:13 2017 +0000 + + [support.runtime] Remove extraneous and misleading parentheses from names of functions and macros + + commit d2fe52eaaf53b6843ab6fe152a2a05e5a7da06fc + Author: Eelis + Date: Thu Feb 16 20:54:49 2017 +0100 + + [alg.min.max] Enlarge lfloor/rfloor delimiters. (#1455) + + commit 7e5537d1e9c7a6d63c9877cf5babde4ddf14807c + Author: Eelis + Date: Wed Feb 15 15:38:19 2017 +0100 + + Parenthesize some \refs. (#1436) + + commit 473966e60653e8e2bc8ed154d8b18a3736f97088 + Author: Jens Maurer + Date: Thu Feb 9 12:14:12 2017 +0100 + + [unord.req] Insert hint is 'p', not 'q' (#1440) + + LWG 2540 changed the hint for insert from 'q' + (a valid and dereferenceable iterator) to 'p' + (a valid, but not necessarily dereferenceable iterator), + but neglected to adjust the description text. + + Fixes #1423. + + commit 90c486f80612c3a7fd26ee408631991814f7b81c + Author: Jens Maurer + Date: Wed Feb 8 17:21:31 2017 +0100 + + [any.assign] Rename T to VT. (#1448) + + These renames were overlooked in commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274. + + Fixes #1443. diff --git a/source/algorithms.tex b/source/algorithms.tex index 9c74d5dfbb..1a8ffe5d77 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -31,54 +31,63 @@ 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 bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{alg.any_of}, any of template bool any_of(InputIterator first, InputIterator last, Predicate pred); - template + template bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{alg.none_of}, none of template bool none_of(InputIterator first, InputIterator last, Predicate pred); - template + template bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); + // \ref{alg.foreach}, for each template Function for_each(InputIterator first, InputIterator last, Function f); - template + template void for_each(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Function f); + ForwardIterator first, ForwardIterator last, Function f); template InputIterator for_each_n(InputIterator first, Size n, Function f); - template - InputIterator for_each_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - InputIterator find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - InputIterator find_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - InputIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - Predicate pred); + template + ForwardIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); + + // \ref{alg.find.end}, find end template ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, @@ -101,6 +110,7 @@ ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + // \ref{alg.find.first.of}, find first template InputIterator find_first_of(InputIterator first1, InputIterator last1, @@ -110,19 +120,20 @@ find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); - template - InputIterator + template + ForwardIterator1 find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2); - template - InputIterator + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + ForwardIterator1 find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + // \ref{alg.adjacent.find}, adjacent find template ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last); @@ -140,21 +151,23 @@ ForwardIterator last, BinaryPredicate pred); + // \ref{alg.count}, count template typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); - template - typename iterator_traits::difference_type + template + typename iterator_traits::difference_type count(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, const T& value); + ForwardIterator first, ForwardIterator last, const T& value); template typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); - template - typename iterator_traits::difference_type + template + typename iterator_traits::difference_type count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); + // \ref{mismatch}, mismatch template pair mismatch(InputIterator1 first1, InputIterator1 last1, @@ -172,30 +185,31 @@ mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); - template - pair + template + pair mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - template - pair + pair mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); - template - pair + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + pair mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template - pair + pair mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + // \ref{alg.equal}, equal template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); @@ -209,26 +223,27 @@ bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); - template + template bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - template bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); - template + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + // \ref{alg.is_permutation}, is permutation template bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); @@ -294,26 +309,26 @@ template OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); - template - OutputIterator copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - OutputIterator copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - OutputIterator copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + 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, @@ -323,11 +338,11 @@ template OutputIterator move(InputIterator first, InputIterator last, OutputIterator result); - template - OutputIterator move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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, @@ -344,6 +359,7 @@ template void iter_swap(ForwardIterator1 a, ForwardIterator2 b); + // \ref{alg.transform}, transform template OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); @@ -352,18 +368,19 @@ OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); - template - OutputIterator transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); - template - OutputIterator transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_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); + // \ref{alg.replace}, replace template void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); @@ -382,22 +399,23 @@ OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); - template - OutputIterator replace_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); - template - OutputIterator replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); + ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + Predicate pred, const T& new_value); + // \ref{alg.fill}, fill template void fill(ForwardIterator first, ForwardIterator last, const T& value); template OutputIterator fill_n(OutputIterator first, Size n, const T& value); - template - OutputIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - OutputIterator first, Size n, const T& value); + ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, const T& value); + // \ref{alg.generate}, generate template void generate(ForwardIterator first, ForwardIterator last, Generator gen); @@ -420,10 +439,11 @@ Generator gen); template OutputIterator generate_n(OutputIterator first, Size n, Generator gen); - template - OutputIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); @@ -441,20 +461,21 @@ template OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); - template - OutputIterator remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator 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); - template - OutputIterator remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator 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); template @@ -473,16 +494,17 @@ template OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); - template - OutputIterator unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result); - template + ForwardIterator2 unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template - OutputIterator unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator 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 void reverse(BidirectionalIterator first, BidirectionalIterator last); template @@ -492,12 +514,13 @@ OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); - template - OutputIterator reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, - BidirectionalIterator last, - OutputIterator result); + template + ForwardIterator reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, + BidirectionalIterator last, + ForwardIterator result); + // \ref{alg.rotate}, rotate template ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, @@ -511,11 +534,11 @@ OutputIterator rotate_copy( ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); - template - OutputIterator rotate_copy( + template + ForwardIterator2 rotate_copy( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result); + 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 bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); template ForwardIterator partition(ForwardIterator first, @@ -558,16 +581,16 @@ template pair - partition_copy(InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, - Predicate pred); - template - pair - partition_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, - Predicate pred); + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, + Predicate pred); + 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, @@ -630,16 +653,17 @@ RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); - template + template RandomAccessIterator partial_sort_copy( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, + ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); - template + template RandomAccessIterator partial_sort_copy( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, + ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); @@ -668,6 +692,7 @@ ForwardIterator first, ForwardIterator last, Compare comp); + // \ref{alg.nth.element}, Nth element template void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); @@ -724,18 +749,18 @@ OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); - template - OutputIterator merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); + template + 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, @@ -763,14 +788,15 @@ template bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); - template + template bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); template OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, @@ -780,18 +806,18 @@ OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); - template - OutputIterator set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - 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); + template + 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( @@ -803,20 +829,20 @@ InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); - template - OutputIterator set_intersection( + template + ForwardIterator set_intersection( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_intersection( + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template + ForwardIterator set_intersection( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template OutputIterator set_difference( @@ -828,20 +854,20 @@ InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); - template - OutputIterator set_difference( + template + ForwardIterator set_difference( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_difference( + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template + ForwardIterator set_difference( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); template OutputIterator set_symmetric_difference( @@ -853,20 +879,20 @@ InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); - template - OutputIterator set_symmetric_difference( + template + ForwardIterator set_symmetric_difference( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_symmetric_difference( + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template + ForwardIterator set_symmetric_difference( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); // \ref{alg.heap.operations}, heap operations template @@ -996,16 +1022,17 @@ InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); - template + template bool lexicographical_compare( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template bool lexicographical_compare( ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); // \ref{alg.permutation.generators}, permutations @@ -1250,10 +1277,14 @@ \rSec2[algorithms.parallel.user]{Requirements on user-provided function objects} \pnum -Function objects passed into parallel algorithms as objects of type -\tcode{Predicate}, \tcode{BinaryPredicate}, \tcode{Compare}, and -\tcode{BinaryOperation} shall not directly or indirectly modify objects via -their arguments. +Unless otherwise specified, function objects passed into parallel algorithms as +objects of type \tcode{Predicate}, \tcode{BinaryPredicate}, \tcode{Compare}, +\tcode{UnaryOperation}, \tcode{BinaryOperation}, \tcode{BinaryOperation1}, +\tcode{BinaryOperation2}, and the operators used by the analogous overloads to +these parallel algorithms that could be formed by the invocation with the +specified default predicate or operation (where applicable) shall not directly +or indirectly modify objects via their arguments, nor shall they rely on the +identity of the provided objects.. \rSec2[algorithms.parallel.exec]{Effect of execution policies on algorithm execution} @@ -1263,6 +1294,19 @@ which describe the manner in which the execution of these algorithms may be parallelized and the manner in which they apply the element access functions. +\pnum +Unless otherwise stated, implementations may make arbitrary copies of elements +(with type \tcode{T}) from sequences where \tcode{is_trivially_copy_constructible_v} +and \tcode{is_trivially_destructible_v} are \tcode{true}. +\begin{note} +This implies that user-supplied function objects should not rely on object +identity of arguments for such input sequences. Users for whom the object +identity of the arguments to these function objects is important should +consider using a wrapping iterator that returns a non-copied implementation +object such as \tcode{reference_wrapper}~(\ref{refwrap}) or some equivalent +solution. +\end{note} + \pnum The invocations of element access functions in parallel algorithms invoked with an execution policy object of type \tcode{execution::sequenced_policy} all occur @@ -1306,7 +1350,7 @@ int a[] = {1,2}; std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { x.fetch_add(1, std::memory_order_relaxed); - // spin wait for another iteration to change the value of x + // spin wait for another iteration to change the value of \tcode{x} while (x.load(std::memory_order_relaxed) == 1) { } // incorrect: assumes execution order }); \end{codeblock} @@ -1335,7 +1379,7 @@ unsequenced with respect to one another within each thread of execution. These threads of execution are either the invoking thread of execution or threads of execution implicitly created by the library; the latter will provide weakly parallel -forward progress guarantees. +forward progress guarantees. \begin{note} This means that multiple function object invocations may be interleaved on a single thread of execution, which overrides the usual guarantee from \ref{intro.execution} @@ -1430,6 +1474,15 @@ Unless otherwise specified, the semantics of \tcode{ExecutionPolicy} algorithm overloads are identical to their overloads without. +\pnum +Unless otherwise specified, the complexity requirements of \tcode{ExecutionPolicy} +algorithm overloads are relaxed from the complexity requirements of the overloads +without as follows: +when the guarantee says ``at most \placeholder{expr}'' or ``exactly \placeholder{expr}'' +and does not specify the number of assignments or swaps, and \placeholder{expr} +is not already expressed with \bigoh{} notation, the complexity of the algorithm +shall be \bigoh{\placeholder{expr}}. + \pnum Parallel algorithms shall not participate in overload resolution unless \tcode{is_execution_policy_v>} is \tcode{true}. @@ -1442,8 +1495,8 @@ \begin{itemdecl} template bool all_of(InputIterator first, InputIterator last, Predicate pred); -template - bool all_of(ExecutionPolicy&& exec, InputIterator first, InputIterator last, +template + bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1463,8 +1516,8 @@ \begin{itemdecl} template bool any_of(InputIterator first, InputIterator last, Predicate pred); -template - bool any_of(ExecutionPolicy&& exec, InputIterator first, InputIterator last, +template + bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1484,8 +1537,8 @@ \begin{itemdecl} template bool none_of(InputIterator first, InputIterator last, Predicate pred); -template - bool none_of(ExecutionPolicy&& exec, InputIterator first, InputIterator last, +template + bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} @@ -1545,9 +1598,9 @@ \indexlibrary{\idxcode{for_each}}% \begin{itemdecl} -template +template void for_each(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, + ForwardIterator first, ForwardIterator last, Function f); \end{itemdecl} @@ -1572,6 +1625,9 @@ \pnum \remarks If \tcode{f} returns a result, the result is ignored. +Implementations do not +have the freedom granted under \ref{algorithms.parallel.exec} to make arbitrary +copies of elements from the input sequence. \pnum \begin{note} @@ -1617,9 +1673,9 @@ \indexlibrary{\idxcode{for_each_n}}% \begin{itemdecl} -template - InputIterator for_each_n(ExecutionPolicy&& exec, InputIterator first, Size n, - Function f); +template + ForwardIterator for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, + Function f); \end{itemdecl} \begin{itemdescr} @@ -1646,9 +1702,12 @@ \pnum \remarks -If \tcode{f} returns a result, the result is ignored. +If \tcode{f} returns a result, the result is ignored. Implementations do not +have the freedom granted under \ref{algorithms.parallel.exec} to make arbitrary +copies of elements from the input sequence. \end{itemdescr} + \rSec2[alg.find]{Find} \indexlibrary{\idxcode{find}}% @@ -1658,23 +1717,23 @@ template InputIterator find(InputIterator first, InputIterator last, const T& value); -template - InputIterator find(ExecutionPolicy&& exec, 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); -template - InputIterator find_if(ExecutionPolicy&& exec, 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); -template - InputIterator find_if_not(ExecutionPolicy&& exec, InputIterator first, InputIterator last, - Predicate pred); +template + ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -1759,11 +1818,11 @@ InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); -template - InputIterator +template + ForwardIterator1 find_first_of(ExecutionPolicy&& exec, - InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template @@ -1771,12 +1830,12 @@ find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); -template - InputIterator + ForwardIterator1 find_first_of(ExecutionPolicy&& exec, - InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); \end{itemdecl} @@ -1846,11 +1905,12 @@ \pnum \complexity -For a nonempty range, exactly +For the overloads with no \tcode{ExecutionPolicy}, exactly \tcode{min((i - first) + 1, (last - first) - 1)} applications of the corresponding predicate, where \tcode{i} is \tcode{adjacent_find}'s -return value. +return value. For the overloads with an \tcode{ExecutionPolicy}, +\bigoh{\tcode{last - first}} applications of the corresponding predicate. \end{itemdescr} \rSec2[alg.count]{Count} @@ -1861,16 +1921,16 @@ template typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); -template - typename iterator_traits::difference_type - count(ExecutionPolicy&& exec, InputIterator first, InputIterator last, const T& value); +template + typename iterator_traits::difference_type + count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); -template - typename iterator_traits::difference_type - count_if(ExecutionPolicy&& exec, InputIterator first, InputIterator last, Predicate pred); +template + typename iterator_traits::difference_type + count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -1898,33 +1958,33 @@ pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); -template - pair +template + pair mismatch(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); template pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); -template - pair + pair mismatch(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); template pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); -template - pair +template + pair mismatch(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template @@ -1932,12 +1992,12 @@ mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); -template - pair + pair mismatch(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); \end{itemdecl} @@ -1971,39 +2031,39 @@ template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); -template +template bool equal(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); -template bool equal(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); -template +template bool equal(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); -template bool equal(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); \end{itemdecl} @@ -2030,15 +2090,44 @@ \pnum \complexity -No applications of the corresponding predicate if +\begin{itemize} +\item +For the overloads with no \tcode{ExecutionPolicy}, +\begin{itemize} +\item +if \tcode{InputIterator1} and \tcode{InputIterator2} -meet the requirements of random access iterators and -\tcode{last1 - first1 != last2 - first2}. -Otherwise, at most -\tcode{min(last1 - first1, last2 - first2)} +meet the requirements of random access iterators~(\ref{random.access.iterators}) +and +\tcode{last1 - first1 != last2 - first2}, +then +no applications of the corresponding predicate; otherwise, + +\item +at most +$\min(\tcode{last1 - first1}, \tcode{last2 - first2})$ applications of the corresponding predicate. +\end{itemize} + +\item +For the overloads with no \tcode{ExecutionPolicy}, +\begin{itemize} +\item +if +\tcode{ForwardIterator1} +and +\tcode{ForwardIterator2} +meet the requirements of random access iterators and +\tcode{last1 - first1 != last2 - first2}, then +no applications of the corresponding predicate; otherwise, + +\item +\bigoh{\min(\tcode{last1 - first1}, \tcode{last2 - first2})} applications +of the corresponding predicate. +\end{itemize} +\end{itemize} \end{itemdescr} \rSec2[alg.is_permutation]{Is permutation} @@ -2075,13 +2164,13 @@ \returns If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. Otherwise return \tcode{true} if there exists a permutation of the elements in the range \range{first2}{first2 + (last1 - first1)}, beginning with \tcode{ForwardIterator2 -begin}, such that \tcode{equal(first1, last1, begin)} returns \tcode{true} or +begin}, such that \tcode{equal(first1, last1, begin)} returns \tcode{true} or \tcode{equal(first1, last1, begin, pred)} returns \tcode{true}; otherwise, returns \tcode{false}. \pnum \complexity No applications of the corresponding predicate if \tcode{ForwardIterator1} -and \tcode{ForwardIter\-ator2} meet the requirements of random access iterators and +and \tcode{Forward\-Iter\-ator2} meet the requirements of random access iterators and \tcode{last1 - first1 != last2 - first2}. Otherwise, exactly \tcode{last1 - first1} applications of the corresponding predicate if \tcode{equal(\brk{}first1, last1, first2, last2)} @@ -2251,9 +2340,10 @@ \indexlibrary{\idxcode{copy}}% \begin{itemdecl} -template - OutputIterator copy(ExecutionPolicy&& policy, InputIterator first, InputIterator last, - OutputIterator result); +template + ForwardIterator2 copy(ExecutionPolicy&& policy, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} @@ -2279,15 +2369,15 @@ template OutputIterator copy_n(InputIterator first, Size n, OutputIterator result); -template - OutputIterator copy_n(ExecutionPolicy&& exec, - InputIterator first, Size n, - OutputIterator result); +template + ForwardIterator2 copy_n(ExecutionPolicy&& exec, + ForwardIterator1 first, Size n, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\effects For each non-negative integer +\effects For each non-negative integer $i < n$, performs \tcode{*(result + i) = *(first + i)}. \pnum @@ -2302,15 +2392,20 @@ template OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); -template - OutputIterator copy_if(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); +template + ForwardIterator2 copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires The ranges \range{first}{last} and \range{result}{result + (last - first)} shall not overlap. +\begin{note} +For the overload with an \tcode{ExecutionPolicy}, there may be a performance +cost if \tcode{iterator_traits::value_type} is not +\tcode{Move\-Constructible} (Table~\ref{tab:moveconstructible}). +\end{note} \pnum \effects Copies all of the elements referred to by the iterator \tcode{i} in the range \range{first}{last} @@ -2408,9 +2503,10 @@ \indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} -template - OutputIterator move(ExecutionPolicy&& policy, - InputIterator first, InputIterator last, OutputIterator result); +template + ForwardIterator2 move(ExecutionPolicy&& policy, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} @@ -2544,12 +2640,12 @@ OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); -template - OutputIterator + ForwardIterator2 transform(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, UnaryOperation op); template @@ -2557,12 +2653,12 @@ transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); -template - OutputIterator +template + ForwardIterator transform(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator result, BinaryOperation binary_op); \end{itemdecl} @@ -2599,7 +2695,8 @@ Exactly \tcode{last1 - first1} applications of -\tcode{op} or \tcode{binary_op}. +\tcode{op} or \tcode{binary_op}. This requirement also applies to the overload +with an \tcode{ExecutionPolicy} . \pnum \remarks @@ -2662,11 +2759,11 @@ replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); -template - OutputIterator +template + ForwardIterator2 replace_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& old_value, const T& new_value); template @@ -2674,12 +2771,12 @@ replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); -template - OutputIterator + ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred, const T& new_value); \end{itemdecl} @@ -2741,9 +2838,9 @@ template OutputIterator fill_n(OutputIterator first, Size n, const T& value); -template - OutputIterator fill_n(ExecutionPolicy&& exec, - OutputIterator first, Size n, const T& value); +template + ForwardIterator fill_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, const T& value); \end{itemdecl} @@ -2789,9 +2886,9 @@ template OutputIterator generate_n(OutputIterator first, Size n, Generator gen); -template - OutputIterator generate_n(ExecutionPolicy&& exec, - OutputIterator first, Size n, Generator gen); +template + ForwardIterator generate_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, Generator gen); \end{itemdecl} \begin{itemdescr} @@ -2889,21 +2986,21 @@ OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); -template - OutputIterator +template + ForwardIterator2 remove_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, const T& value); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); template OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); -template - OutputIterator +template + ForwardIterator2 remove_copy_if(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -2914,6 +3011,11 @@ and \range{result}{result + (last - first)} shall not overlap. The expression \tcode{*result = *first} shall be valid. +\begin{note} +For the overloads with an \tcode{ExecutionPolicy}, there may be a performance +cost if \tcode{iterator_traits::value_type} is not +\tcode{Move\-Constructible} (Table~\ref{tab:moveconstructible}). +\end{note} \pnum \effects @@ -2993,46 +3095,61 @@ OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result); -template - OutputIterator +template + ForwardIterator2 unique_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); template OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); -template - OutputIterator + ForwardIterator2 unique_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires +\begin{itemize} +\item The comparison function shall be an equivalence relation. + +\item The ranges \range{first}{last} and \range{result}{result+(last-first)} -shall not overlap. The expression +shall not overlap. + +\item +The expression \tcode{*result = *first} shall be valid. -Let \tcode{T} be the value type of \tcode{InputIterator}. + +\item +For the overloads with no \tcode{ExecutionPolicy}, +let \tcode{T} be the value type of \tcode{InputIterator}. If \tcode{InputIterator} meets the forward iterator requirements, then there are no additional requirements for \tcode{T}. Otherwise, if \tcode{OutputIterator} meets the forward iterator requirements and its value type is the same as \tcode{T}, then \tcode{T} shall be \tcode{CopyAssignable} (Table~\ref{tab:copyassignable}). Otherwise, \tcode{T} shall be both -\tcode{CopyConstructible} (Table~\ref{tab:copyconstructible}) and -\tcode{CopyAssignable}. +\tcode{CopyConstructible} (Table~\ref{tab:copyconstructible}) and \tcode{CopyAssignable}. +\begin{note} +For the overloads with an \tcode{ExecutionPolicy}, there may be a performance +cost if the value type of \tcode{ForwardIterator1} is not both +\tcode{CopyConstructible} and \tcode{CopyAssignable}. +\end{note} +\end{itemize} \pnum \effects @@ -3100,11 +3217,11 @@ OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); -template - OutputIterator +template + ForwardIterator reverse_copy(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, - OutputIterator result); + ForwardIterator result); \end{itemdecl} \begin{itemdescr} @@ -3196,11 +3313,11 @@ OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); -template - OutputIterator +template + ForwardIterator2 rotate_copy(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator middle, ForwardIterator last, - OutputIterator result); + ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} @@ -3502,7 +3619,7 @@ \pnum \complexity -\bigoh{N\log(N)} comparisons, where $N = \tcode{last - first}$. +\bigoh{N \log N} comparisons, where $N = \tcode{last - first}$. \end{itemdescr} \rSec3[stable.sort]{\tcode{stable_sort}} @@ -3541,7 +3658,7 @@ \complexity At most $N \log^2(N)$ comparisons, where -$N = \tcode{last - first}$, but only $N \log(N)$ comparisons if there is enough extra memory. +$N = \tcode{last - first}$, but only $N \log N$ comparisons if there is enough extra memory. \pnum \remarks Stable~(\ref{algorithm.stable}). @@ -3599,7 +3716,7 @@ \pnum \complexity -It takes approximately +Approximately \tcode{(last - first) * log(middle - first)} comparisons. \end{itemdescr} @@ -3613,10 +3730,10 @@ partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); -template +template RandomAccessIterator partial_sort_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, + ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); @@ -3627,11 +3744,11 @@ RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); -template RandomAccessIterator partial_sort_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, + ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); @@ -3803,7 +3920,9 @@ \pnum \complexity -Linear on average. +For the overloads with no \tcode{ExecutionPolicy}, linear on average. +For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N} applications of +the predicate, and \bigoh{N \log N} swaps, where $N = \tcode{last - first}$. \end{itemdescr} \rSec2[alg.binary.search]{Binary search} @@ -4045,14 +4164,18 @@ \begin{itemdecl} template bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); -template +template bool is_partitioned(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, Predicate pred); + ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{InputIterator}'s value type shall be convertible to \tcode{Predicate}'s argument type. +\requires For the overload with no \tcode{ExecutionPolicy}, +\tcode{InputIterator}'s value type shall be convertible to \tcode{Predicate}'s +argument type. For the overload with an \tcode{ExecutionPolicy}, +\tcode{ForwardIterator}'s value type shall be convertible to \tcode{Predicate}'s +argument type. \pnum \returns \tcode{true} if @@ -4089,9 +4212,15 @@ range \range{i}{last}, \tcode{pred(*k) == false}. \pnum -\complexity If \tcode{ForwardIterator} meets the requirements for a \tcode{BidirectionalIterator}, at most -\tcode{(last - first) / 2} swaps are done; otherwise at most \tcode{last - first} swaps -are done. Exactly \tcode{last - first} applications of the predicate are done. +\complexity Let $N = \tcode{last - first}$: +\begin{itemize} +\item For the overload with no \tcode{ExecutionPolicy}, exactly $N$ applications +of the predicate. At most $N / 2$ swaps if \tcode{ForwardIterator} meets the +\tcode{BidirectionalIterator} requirements and at most $N$ swaps otherwise. +\item For the overload with an \tcode{ExecutionPolicy}, +\bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. +\end{itemize} + \end{itemdescr} \indexlibrary{\idxcode{stable_partition}}% @@ -4141,11 +4270,15 @@ \pnum \complexity -At most $N \log(N)$ swaps, where $N = \tcode{last - first}$, -but only \bigoh{N} swaps if there is enough extra memory. -Exactly -\tcode{last - first} +Let $N$ = \tcode{last - first}: +\begin{itemize} +\item For the overload with no \tcode{ExecutionPolicy}, at most $N \log N$ swaps, +but only \bigoh{N} swaps if there is enough extra memory. Exactly $N$ applications of the predicate. +\item For the overload with an \tcode{ExecutionPolicy}, +\bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. +\end{itemize} + \end{itemdescr} \indexlibrary{\idxcode{partition_copy}}% @@ -4156,22 +4289,40 @@ partition_copy(InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); -template - pair +template + pair partition_copy(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, + ForwardIterator first, ForwardIterator last, + ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{InputIterator}'s value type shall be \tcode{CopyAssignable}, and shall be -writable~(\ref{iterator.requirements.general}) to the \tcode{out_true} and \tcode{out_false} \tcode{OutputIterator}s, and shall be -convertible to \tcode{Predicate}'s argument type. The input range shall not overlap with -either of the output ranges. +\requires +\begin{itemize} +\item +For the overload with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s +value type shall be \tcode{CopyAssignable} (Table~\ref{tab:copyassignable}), +and shall be writable~(\ref{iterator.requirements.general}) to the \tcode{out_true} +and \tcode{out_false} \tcode{OutputIterator}s, and shall be convertible to +\tcode{Predicate}'s argument type. + +\item +For the overload with an \tcode{ExecutionPolicy}, \tcode{ForwardIterator}'s +value type shall be \tcode{Copy\-Assign\-able}, and shall be writable to the +\tcode{out_true} and \tcode{out_false} \tcode{ForwardIterator}s, and shall be +convertible to \tcode{Predicate}'s argument type. +\begin{note} +There may be a performance cost if \tcode{ForwardIterator}'s value type is not +\tcode{CopyConstructible}. +\end{note} + +\item +For both overloads, the input range shall not overlap with either of the output ranges. +\end{itemize} \pnum \effects For each iterator \tcode{i} in \range{first}{last}, copies \tcode{*i} to the output range beginning with \tcode{out_true} if \tcode{pred(*i)} is \tcode{true}, or to the output range beginning with \tcode{out_false} otherwise. @@ -4213,13 +4364,13 @@ merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); -template - OutputIterator +template + ForwardIterator merge(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template @@ -4227,13 +4378,13 @@ merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); -template - OutputIterator +template + ForwardIterator merge(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4253,10 +4404,11 @@ \tcode{result + (last1 - first1) + (last2 - first2)}. \pnum -\complexity -At most -\tcode{(last1 - first1) + (last2 - first2) - 1} -comparisons. +\complexity Let $N = \tcode{(last1 - first1) + (last2 - first2)}$: +\begin{itemize} +\item For the overloads with no \tcode{ExecutionPolicy}, at most $N - 1$ comparisons. +\item For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N} comparisons. +\end{itemize} \pnum \remarks Stable~(\ref{algorithm.stable}). @@ -4318,12 +4470,15 @@ will be \tcode{false}. \pnum -\complexity -When enough additional memory is available, -\tcode{(last - first) - 1} -comparisons. -If no additional memory is available, an algorithm with complexity -$N \log(N)$ may be used, where $N = \tcode{last - first}$. +\complexity Let $N = \tcode{last - first}$: +\begin{itemize} +\item For the overloads with no \tcode{ExecutionPolicy}, if enough additional +memory is available, exactly $N - 1$ comparisons. +\item For the overloads with no \tcode{ExecutionPolicy} if no additional +memory is available, \bigoh{N \log N} comparisons. +\item For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N \log N} comparisons. +\end{itemize} + \pnum \remarks Stable~(\ref{algorithm.stable}). @@ -4351,19 +4506,19 @@ template bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); -template +template bool includes(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); -template +template bool includes(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); \end{itemdecl} @@ -4397,13 +4552,13 @@ set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); -template - OutputIterator +template + ForwardIterator set_union(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template @@ -4411,13 +4566,13 @@ set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); -template - OutputIterator +template + ForwardIterator set_union(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4458,13 +4613,13 @@ set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); -template - OutputIterator +template + ForwardIterator set_intersection(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template @@ -4472,13 +4627,13 @@ set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); -template - OutputIterator +template + ForwardIterator set_intersection(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4518,13 +4673,13 @@ set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); -template - OutputIterator +template + ForwardIterator set_difference(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template @@ -4532,13 +4687,13 @@ set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); -template - OutputIterator +template + ForwardIterator set_difference(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4591,13 +4746,13 @@ set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); -template - OutputIterator +template + ForwardIterator set_symmetric_difference(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template @@ -4605,13 +4760,13 @@ set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); -template - OutputIterator +template + ForwardIterator set_symmetric_difference(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -4648,7 +4803,7 @@ If \range{first1}{last1} contains $m$ elements that are equivalent to each other and \range{first2}{last2} contains $n$ elements that are equivalent to them, then $|m - n|$ of those elements shall be copied to the output range: the last -$m - n$ of these elements from \range{first1}{last1} if $m > n$, and the last +$m - n$ of these elements from \range{first1}{last1} if $m > n$, and the last $n - m$ of these elements from \range{first2}{last2} if $m < n$. \end{itemdescr} @@ -4670,7 +4825,7 @@ or a new element added by \tcode{push_heap()}, in -\bigoh{\log(N)} +\bigoh{\log N} time. \end{itemize} @@ -4822,7 +4977,7 @@ \pnum \complexity -At most $N \log(N)$ +At most $N \log N$ comparisons, where $N = \tcode{last - first}$. \end{itemdescr} @@ -5183,14 +5338,15 @@ \returns \tcode{make_pair(first, first)} if \range{first}{last} is empty, otherwise \tcode{make_pair(m, M)}, where \tcode{m} is -the first iterator in \range{first}{last} such that no iterator in the range refers to a smaller element, and where \tcode{M} is the last iterator -\footnote{This behavior intentionally differs from \tcode{max_element()}.} +the first iterator in \range{first}{last} such that no iterator in the range refers +to a smaller element, and where \tcode{M} is the last iterator\footnote{This behavior +intentionally differs from \tcode{max_element()}.} in \range{first}{last} such that no iterator in the range refers to a larger element. \pnum \complexity At most -$\max(\lfloor{\frac{3}{2}} (N-1)\rfloor, 0)$ +$\max(\bigl\lfloor{\frac{3}{2}} (N-1)\bigr\rfloor, 0)$ applications of the corresponding predicate, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -5235,22 +5391,22 @@ bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); -template +template bool lexicographical_compare(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); -template +template bool lexicographical_compare(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); \end{itemdecl} diff --git a/source/atomics.tex b/source/atomics.tex index 5be09daa19..0f55b417ca 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -49,132 +49,190 @@ #define ATOMIC_LLONG_LOCK_FREE @\unspec@ #define ATOMIC_POINTER_LOCK_FREE @\unspec@ - // \ref{atomics.types.generic}, generic types + // \ref{atomics.types.generic}, atomic template struct atomic; - template<> struct atomic<@\placeholder{integral}@>; + // \ref{atomics.types.pointer}, partial specialization for pointers template struct atomic; - // \ref{atomics.types.operations.general}, general operations on atomic types - // In the following declarations, \tcode{\placeholder{atomic-type}} is either \tcode{atomic} or a named base class - // for \tcode{T} from Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs} or from \tcode{bool}. If it is \tcode{atomic}, - // then the declaration is a template declaration prefixed with \tcode{template }. - bool atomic_is_lock_free(const volatile @\placeholder{atomic-type}@*) noexcept; - bool atomic_is_lock_free(const @\placeholder{atomic-type}@*) noexcept; - void atomic_init(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - void atomic_init(@\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - void atomic_store(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - void atomic_store(@\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - void atomic_store_explicit(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T, memory_order) noexcept; - void atomic_store_explicit(@\placeholder{atomic-type}@*@\itcorr[-1]@, T, memory_order) noexcept; - T atomic_load(const volatile @\placeholder{atomic-type}@*) noexcept; - T atomic_load(const @\placeholder{atomic-type}@*) noexcept; - T atomic_load_explicit(const volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, memory_order) noexcept; - T atomic_load_explicit(const @\placeholder{atomic-type}@*@\itcorr[-1]@, memory_order) noexcept; - T atomic_exchange(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - T atomic_exchange(@\placeholder{atomic-type}@*@\itcorr[-1]@, T) noexcept; - T atomic_exchange_explicit(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T, memory_order) noexcept; - T atomic_exchange_explicit(@\placeholder{atomic-type}@*@\itcorr[-1]@, T, memory_order) noexcept; - bool atomic_compare_exchange_weak(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T) noexcept; - bool atomic_compare_exchange_weak(@\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T) noexcept; - bool atomic_compare_exchange_strong(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T) noexcept; - bool atomic_compare_exchange_strong(@\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T) noexcept; - bool atomic_compare_exchange_weak_explicit(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_weak_explicit(@\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_strong_explicit(volatile @\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_strong_explicit(@\placeholder{atomic-type}@*@\itcorr[-1]@, T*, T, - memory_order, memory_order) noexcept; - - // \ref{atomics.types.operations.templ}, templated operations on atomic types - template - T atomic_fetch_add(volatile @atomic@*, T) noexcept; - template - T atomic_fetch_add(@atomic@*, T) noexcept; - template - T atomic_fetch_add_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_add_explicit(atomic*, T, memory_order) noexcept; - template - T atomic_fetch_sub(volatile atomic*, T) noexcept; - template - T atomic_fetch_sub(atomic*, T) noexcept; - template - T atomic_fetch_sub_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_sub_explicit(atomic*, T, memory_order) noexcept; + // \ref{atomics.nonmembers}, non-member functions + template + bool atomic_is_lock_free(const volatile atomic*) noexcept; + template + bool atomic_is_lock_free(const atomic*) noexcept; + template + void atomic_init(volatile atomic*, typename atomic::value_type) noexcept; + template + void atomic_init(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store(volatile atomic*, typename atomic::value_type) noexcept; + template + void atomic_store(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + void atomic_store_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + template + T atomic_load(const volatile atomic*) noexcept; + template + T atomic_load(const atomic*) noexcept; + template + T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; + template + T atomic_load_explicit(const atomic*, memory_order) noexcept; + template + T atomic_exchange(volatile atomic*, T) noexcept; + template + T atomic_exchange(atomic*, typename atomic::value_type) noexcept; + template + T atomic_exchange_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + T atomic_exchange_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + template + bool atomic_compare_exchange_weak(volatile atomic*, + typename atomic::value_type*, + typename atomic::value_type) noexcept; + template + bool atomic_compare_exchange_weak(atomic*, + typename atomic::value_type*, + typename atomic::value_type) noexcept; + template + bool atomic_compare_exchange_strong(volatile atomic*, + typename atomic::value_type*, + typename atomic::value_type) noexcept; + template + bool atomic_compare_exchange_strong(atomic*, + typename atomic::value_type*, + typename atomic::value_type) noexcept; + template + bool atomic_compare_exchange_weak_explicit(volatile atomic*, + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; + template + bool atomic_compare_exchange_weak_explicit(atomic*, + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; + template + bool atomic_compare_exchange_strong_explicit(volatile atomic*, + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; + template + bool atomic_compare_exchange_strong_explicit(atomic*, + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; + template - T atomic_fetch_and(volatile atomic*, T) noexcept; + T atomic_fetch_add(volatile atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_and(atomic*, T) noexcept; + T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_and_explicit(volatile atomic*, T, memory_order) noexcept; + T atomic_fetch_add_explicit(volatile atomic*, typename atomic::difference_type, + memory_order) noexcept; template - T atomic_fetch_and_explicit(atomic*, T, memory_order) noexcept; + T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, + memory_order) noexcept; template - T atomic_fetch_or(volatile atomic*, T) noexcept; + T atomic_fetch_sub(volatile atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_or(atomic*, T) noexcept; + T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_or_explicit(volatile atomic*, T, memory_order) noexcept; + T atomic_fetch_sub_explicit(volatile atomic*, typename atomic::difference_type, + memory_order) noexcept; template - T atomic_fetch_or_explicit(atomic*, T, memory_order) noexcept; + T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, + memory_order) noexcept; template - T atomic_fetch_xor(volatile atomic*, T) noexcept; + T atomic_fetch_and(volatile atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_xor(atomic*, T) noexcept; + T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_xor_explicit(volatile atomic*, T, memory_order) noexcept; + T atomic_fetch_and_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; template - T atomic_fetch_xor_explicit(atomic*, T, memory_order) noexcept; - - // \ref{atomics.types.operations.arith}, arithmetic operations on atomic types - // In the following declarations, \tcode{\placeholder{atomic-integral}} is either \tcode{atomic} or a named base class - // for \tcode{T} from Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. If it is \tcode{atomic}, then the declaration - // is a template specialization declaration prefixed with \tcode{template <>}. - @\placeholdernc{integral}@ atomic_fetch_add(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_add(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_add_explicit(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_add_explicit(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_sub(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_sub(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_sub_explicit(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_sub_explicit(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_and(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_and(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_and_explicit(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_and_explicit(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_or(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_or(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_or_explicit(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_or_explicit(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_xor(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_xor(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ atomic_fetch_xor_explicit(volatile @\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - @\placeholdernc{integral}@ atomic_fetch_xor_explicit(@\placeholder{atomic-integral}@*@\itcorr[-1]@, @\placeholdernc{integral}@, memory_order) noexcept; - - // \ref{atomics.types.operations.pointer}, non-member overloads for atomic + T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; template - T* atomic_fetch_add(volatile atomic*, ptrdiff_t) noexcept; + T atomic_fetch_or(volatile atomic*, typename atomic::value_type) noexcept; template - T* atomic_fetch_add(atomic*, ptrdiff_t) noexcept; + T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; template - T* atomic_fetch_add_explicit(volatile atomic*, ptrdiff_t, memory_order) noexcept; + T atomic_fetch_or_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; template - T* atomic_fetch_add_explicit(atomic*, ptrdiff_t, memory_order) noexcept; + T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; template - T* atomic_fetch_sub(volatile atomic*, ptrdiff_t) noexcept; + T atomic_fetch_xor(volatile atomic*, typename atomic::value_type) noexcept; template - T* atomic_fetch_sub(atomic*, ptrdiff_t) noexcept; + T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; template - T* atomic_fetch_sub_explicit(volatile atomic*, ptrdiff_t, memory_order) noexcept; + T atomic_fetch_xor_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; template - T* atomic_fetch_sub_explicit(atomic*, ptrdiff_t, memory_order) noexcept; + T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; - // \ref{atomics.types.operations.req}, initialization + // \ref{atomics.types.operations}, initialization #define ATOMIC_VAR_INIT(value) @\seebelow@ + // \ref{atomics.alias}, type aliases + using atomic_bool = atomic; + using atomic_char = atomic; + using atomic_schar = atomic; + using atomic_uchar = atomic; + using atomic_short = atomic; + using atomic_ushort = atomic; + using atomic_int = atomic; + using atomic_uint = atomic; + using atomic_long = atomic; + using atomic_ulong = atomic; + using atomic_llong = atomic; + using atomic_ullong = atomic; + using atomic_char16_t = atomic; + using atomic_char32_t = atomic; + using atomic_wchar_t = atomic; + + using atomic_int8_t = atomic; + using atomic_uint8_t = atomic; + using atomic_int16_t = atomic; + using atomic_uint16_t = atomic; + using atomic_int32_t = atomic; + using atomic_uint32_t = atomic; + using atomic_int64_t = atomic; + using atomic_uint64_t = atomic; + + using atomic_int_least8_t = atomic; + using atomic_uint_least8_t = atomic; + using atomic_int_least16_t = atomic; + using atomic_uint_least16_t = atomic; + using atomic_int_least32_t = atomic; + using atomic_uint_least32_t = atomic; + using atomic_int_least64_t = atomic; + using atomic_uint_least64_t = atomic; + + using atomic_int_fast8_t = atomic; + using atomic_uint_fast8_t = atomic; + using atomic_int_fast16_t = atomic; + using atomic_uint_fast16_t = atomic; + using atomic_int_fast32_t = atomic; + using atomic_uint_fast32_t = atomic; + using atomic_int_fast64_t = atomic; + using atomic_uint_fast64_t = atomic; + + using atomic_intptr_t = atomic; + using atomic_uintptr_t = atomic; + using atomic_size_t = atomic; + using atomic_ptrdiff_t = atomic; + using atomic_intmax_t = atomic; + using atomic_uintmax_t = atomic; + // \ref{atomics.flag}, flag type and operations struct atomic_flag; bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; @@ -193,12 +251,66 @@ } \end{codeblock} +\rSec1[atomics.alias]{Type aliases} +\indexlibrary{\idxcode{atomic_bool}}% +\indexlibrary{\idxcode{atomic_char}}% +\indexlibrary{\idxcode{atomic_schar}}% +\indexlibrary{\idxcode{atomic_uchar}}% +\indexlibrary{\idxcode{atomic_short}}% +\indexlibrary{\idxcode{atomic_ushort}}% +\indexlibrary{\idxcode{atomic_int}}% +\indexlibrary{\idxcode{atomic_uint}}% +\indexlibrary{\idxcode{atomic_long}}% +\indexlibrary{\idxcode{atomic_ulong}}% +\indexlibrary{\idxcode{atomic_llong}}% +\indexlibrary{\idxcode{atomic_ullong}}% +\indexlibrary{\idxcode{atomic_char16_t}}% +\indexlibrary{\idxcode{atomic_char32_t}}% +\indexlibrary{\idxcode{atomic_wchar_t}}% +\indexlibrary{\idxcode{atomic_int8_t}}% +\indexlibrary{\idxcode{atomic_uint8_t}}% +\indexlibrary{\idxcode{atomic_int16_t}}% +\indexlibrary{\idxcode{atomic_uint16_t}}% +\indexlibrary{\idxcode{atomic_int32_t}}% +\indexlibrary{\idxcode{atomic_uint32_t}}% +\indexlibrary{\idxcode{atomic_int64_t}}% +\indexlibrary{\idxcode{atomic_uint64_t}}% +\indexlibrary{\idxcode{atomic_int_least8_t}}% +\indexlibrary{\idxcode{atomic_uint_least8_t}}% +\indexlibrary{\idxcode{atomic_int_least16_t}}% +\indexlibrary{\idxcode{atomic_uint_least16_t}}% +\indexlibrary{\idxcode{atomic_int_least32_t}}% +\indexlibrary{\idxcode{atomic_uint_least32_t}}% +\indexlibrary{\idxcode{atomic_int_least64_t}}% +\indexlibrary{\idxcode{atomic_uint_least64_t}}% +\indexlibrary{\idxcode{atomic_int_fast8_t}}% +\indexlibrary{\idxcode{atomic_uint_fast8_t}}% +\indexlibrary{\idxcode{atomic_int_fast16_t}}% +\indexlibrary{\idxcode{atomic_uint_fast16_t}}% +\indexlibrary{\idxcode{atomic_int_fast32_t}}% +\indexlibrary{\idxcode{atomic_uint_fast32_t}}% +\indexlibrary{\idxcode{atomic_int_fast64_t}}% +\indexlibrary{\idxcode{atomic_uint_fast64_t}}% +\indexlibrary{\idxcode{atomic_intptr_t}}% +\indexlibrary{\idxcode{atomic_uintptr_t}}% +\indexlibrary{\idxcode{atomic_size_t}}% +\indexlibrary{\idxcode{atomic_ptrdiff_t}}% +\indexlibrary{\idxcode{atomic_intmax_t}}% +\indexlibrary{\idxcode{atomic_uintmax_t}}% +\pnum +The type aliases \tcode{atomic_int$N$_t}, \tcode{atomic_uint$N$_t}, +\tcode{atomic_intptr_t}, and \tcode{atomic_uintptr_t} +are defined if and only if +\tcode{int$N$_t}, \tcode{uint$N$_t}, +\tcode{intptr_t}, and \tcode{uintptr_t} +are defined, respectively. + \rSec1[atomics.order]{Order and consistency} \begin{codeblock} namespace std { enum memory_order { - memory_order_relaxed, memory_order_consume, memory_order_acquire, + memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst }; } @@ -430,14 +542,13 @@ mapped into a process more than once and by memory that is shared between two processes. \end{note} -\rSec1[atomics.types.generic]{Atomic types} +\rSec1[atomics.types.generic]{Class template \tcode{atomic}} \indexlibrary{\idxcode{atomic}}% -\indexlibrary{\idxcode{atomic}}% -\indexlibrary{\idxcode{atomic<\placeholder{integral}>}}% \begin{codeblock} namespace std { 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; @@ -466,375 +577,36 @@ T operator=(T) volatile noexcept; T operator=(T) noexcept; }; - - template <> struct atomic<@\placeholder{integral}@> { - 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; - 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; - bool compare_exchange_weak(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order, memory_order) noexcept; - bool compare_exchange_strong(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order, memory_order) noexcept; - bool compare_exchange_weak(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(@\placeholder{integral}@&,@\itcorr[-1]@ @\placeholdernc{integral}@, - memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(@\placeholder{integral}@&,@\itcorr[-1]@ @\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; - - atomic() noexcept = default; - constexpr atomic(@\placeholdernc{integral}@) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - @\placeholdernc{integral}@ operator=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator=(@\placeholdernc{integral}@) noexcept; - - @\placeholdernc{integral}@ operator++(int) volatile noexcept; - @\placeholdernc{integral}@ operator++(int) noexcept; - @\placeholdernc{integral}@ operator--(int) volatile noexcept; - @\placeholdernc{integral}@ operator--(int) noexcept; - @\placeholdernc{integral}@ operator++() volatile noexcept; - @\placeholdernc{integral}@ operator++() noexcept; - @\placeholdernc{integral}@ operator--() volatile noexcept; - @\placeholdernc{integral}@ operator--() noexcept; - @\placeholdernc{integral}@ operator+=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator+=(@\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ operator-=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator-=(@\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ operator&=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator&=(@\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ operator|=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator|=(@\placeholdernc{integral}@) noexcept; - @\placeholdernc{integral}@ operator^=(@\placeholdernc{integral}@) volatile noexcept; - @\placeholdernc{integral}@ operator^=(@\placeholdernc{integral}@) noexcept; - }; - - template struct atomic { - 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; - operator T*() const volatile noexcept; - operator T*() const noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; - bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; - - atomic() noexcept = default; - constexpr atomic(T*) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - T* operator=(T*) volatile noexcept; - T* operator=(T*) noexcept; - - T* operator++(int) volatile noexcept; - T* operator++(int) noexcept; - T* operator--(int) volatile noexcept; - T* operator--(int) noexcept; - T* operator++() volatile noexcept; - T* operator++() noexcept; - T* operator--() volatile noexcept; - T* operator--() noexcept; - T* operator+=(ptrdiff_t) volatile noexcept; - T* operator+=(ptrdiff_t) noexcept; - T* operator-=(ptrdiff_t) volatile noexcept; - T* operator-=(ptrdiff_t) noexcept; - }; } \end{codeblock} \indexlibrary{\idxcode{atomic}}% \pnum -There is a generic class template \tcode{atomic}. The type of the template argument +The template argument for \tcode{T} shall be trivially copyable~(\ref{basic.types}). \begin{note} Type arguments that are not also statically initializable may be difficult to use. \end{note} \pnum -The semantics of the operations on specializations of \tcode{atomic} are defined -in~\ref{atomics.types.operations}. - -\pnum -Specializations and instantiations of the \tcode{atomic} template shall have a deleted copy constructor, a deleted -copy assignment operator, and a constexpr value constructor. - -\indexlibrary{\idxcode{atomic<\placeholder{integral}>}}% -\pnum -There shall be explicit specializations of the \tcode{atomic} -template for the integral types -\tcode{char}, -\tcode{signed char}, -\tcode{unsigned char}, -\tcode{short}, -\tcode{unsigned short}, -\tcode{int}, -\tcode{unsigned int}, -\tcode{long}, -\tcode{unsigned long}, -\tcode{long long}, -\tcode{unsigned long long}, -\tcode{char16_t}, -\tcode{char32_t}, -\tcode{wchar_t}, -and any other types needed by the typedefs in the header \tcode{}. -For each integral type \tcode{\placeholder{integral}}, the specialization -\tcode{atomic<\placeholder{integral}>} provides additional atomic operations appropriate to integral types. -There shall be a specialization \tcode{atomic} which provides the general -atomic operations as specified in \ref{atomics.types.operations.general}. - -\pnum -The atomic integral specializations and the specialization \tcode{atomic} -shall be standard-layout structs. They shall each have a trivial default constructor -and a trivial destructor. They shall each support aggregate initialization -syntax. - -\indexlibrary{\idxcode{atomic}}% -\pnum -There shall be pointer partial specializations of the \tcode{atomic} class template. -These specializations shall be standard-layout structs. -They shall each have a trivial default constructor and a trivial destructor. -They shall each support aggregate initialization syntax. - -\indexlibrary{\idxcode{atomic_bool}}% -\pnum -There shall be named types corresponding to the integral specializations of -\tcode{atomic}, as specified in Table~\ref{tab:atomics.integral}, and a named type -\tcode{atomic_bool} corresponding to the specified \tcode{atomic}. Each named -type is either a typedef to the corresponding specialization or a base class of the -corresponding specialization. If it is a base class, it shall support the same -member functions as the corresponding specialization. - -\indexlibrary{\idxcode{atomic_char}}% -\indexlibrary{\idxcode{atomic_schar}}% -\indexlibrary{\idxcode{atomic_uchar}}% -\indexlibrary{\idxcode{atomic_short}}% -\indexlibrary{\idxcode{atomic_ushort}}% -\indexlibrary{\idxcode{atomic_int}}% -\indexlibrary{\idxcode{atomic_uint}}% -\indexlibrary{\idxcode{atomic_long}}% -\indexlibrary{\idxcode{atomic_ulong}}% -\indexlibrary{\idxcode{atomic_llong}}% -\indexlibrary{\idxcode{atomic_ullong}}% -\indexlibrary{\idxcode{atomic_char16_t}}% -\indexlibrary{\idxcode{atomic_char32_t}}% -\indexlibrary{\idxcode{atomic_wchar_t}}% -\begin{floattablebase} -{Named atomic types}{tab:atomics.integral}{ll}{ht} -\hline -\textbf{Named atomic type} & \textbf{Corresponding non-atomic type} \\ \hline -\tcode{atomic_char} & \tcode{char} \\ -\tcode{atomic_schar} & \tcode{signed char} \\ -\tcode{atomic_uchar} & \tcode{unsigned char} \\ -\tcode{atomic_short} & \tcode{short} \\ -\tcode{atomic_ushort} & \tcode{unsigned short} \\ -\tcode{atomic_int} & \tcode{int} \\ -\tcode{atomic_uint} & \tcode{unsigned int} \\ -\tcode{atomic_long} & \tcode{long} \\ -\tcode{atomic_ulong} & \tcode{unsigned long} \\ -\tcode{atomic_llong} & \tcode{long long} \\ -\tcode{atomic_ullong} & \tcode{unsigned long long} \\ -\tcode{atomic_char16_t} & \tcode{char16_t} \\ -\tcode{atomic_char32_t} & \tcode{char32_t} \\ -\tcode{atomic_wchar_t} & \tcode{wchar_t} \\ -\hline -\end{floattablebase} - -\pnum -There shall be atomic typedefs corresponding to non-atomic typedefs as -specified in Table~\ref{tab:atomics.typedefs}. -\tcode{atomic_int$N$_t}, \tcode{atomic_uint$N$_t}, -\tcode{atomic_intptr_t}, and \tcode{atomic_uintptr_t} -shall be defined if and only if -\tcode{int$N$_t}, \tcode{uint$N$_t}, -\tcode{intptr_t}, and \tcode{uintptr_t} -are defined, respectively. - -\indexlibrary{\idxcode{atomic_int8_t}}% -\indexlibrary{\idxcode{atomic_uint8_t}}% -\indexlibrary{\idxcode{atomic_int16_t}}% -\indexlibrary{\idxcode{atomic_uint16_t}}% -\indexlibrary{\idxcode{atomic_int32_t}}% -\indexlibrary{\idxcode{atomic_uint32_t}}% -\indexlibrary{\idxcode{atomic_int64_t}}% -\indexlibrary{\idxcode{atomic_uint64_t}}% -\indexlibrary{\idxcode{atomic_int_least8_t}}% -\indexlibrary{\idxcode{atomic_uint_least8_t}}% -\indexlibrary{\idxcode{atomic_int_least16_t}}% -\indexlibrary{\idxcode{atomic_uint_least16_t}}% -\indexlibrary{\idxcode{atomic_int_least32_t}}% -\indexlibrary{\idxcode{atomic_uint_least32_t}}% -\indexlibrary{\idxcode{atomic_int_least64_t}}% -\indexlibrary{\idxcode{atomic_uint_least64_t}}% -\indexlibrary{\idxcode{atomic_int_fast8_t}}% -\indexlibrary{\idxcode{atomic_uint_fast8_t}}% -\indexlibrary{\idxcode{atomic_int_fast16_t}}% -\indexlibrary{\idxcode{atomic_uint_fast16_t}}% -\indexlibrary{\idxcode{atomic_int_fast32_t}}% -\indexlibrary{\idxcode{atomic_uint_fast32_t}}% -\indexlibrary{\idxcode{atomic_int_fast64_t}}% -\indexlibrary{\idxcode{atomic_uint_fast64_t}}% -\indexlibrary{\idxcode{atomic_intptr_t}}% -\indexlibrary{\idxcode{atomic_uintptr_t}}% -\indexlibrary{\idxcode{atomic_size_t}}% -\indexlibrary{\idxcode{atomic_ptrdiff_t}}% -\indexlibrary{\idxcode{atomic_intmax_t}}% -\indexlibrary{\idxcode{atomic_uintmax_t}}% -\begin{floattablebase} -{Atomic typedefs}{tab:atomics.typedefs}{ll}{ht} -\hline -\textbf{Atomic typedef} & \textbf{Corresponding non-atomic typedef} \\ \hline -\tcode{atomic_int8_t} & \tcode{int8_t} \\ -\tcode{atomic_uint8_t} & \tcode{uint8_t} \\ -\tcode{atomic_int16_t} & \tcode{int16_t} \\ -\tcode{atomic_uint16_t} & \tcode{uint16_t} \\ -\tcode{atomic_int32_t} & \tcode{int32_t} \\ -\tcode{atomic_uint32_t} & \tcode{uint32_t} \\ -\tcode{atomic_int64_t} & \tcode{int64_t} \\ -\tcode{atomic_uint64_t} & \tcode{uint64_t} \\ -\tcode{atomic_int_least8_t} & \tcode{int_least8_t} \\ -\tcode{atomic_uint_least8_t} & \tcode{uint_least8_t} \\ -\tcode{atomic_int_least16_t} & \tcode{int_least16_t} \\ -\tcode{atomic_uint_least16_t} & \tcode{uint_least16_t} \\ -\tcode{atomic_int_least32_t} & \tcode{int_least32_t} \\ -\tcode{atomic_uint_least32_t} & \tcode{uint_least32_t} \\ -\tcode{atomic_int_least64_t} & \tcode{int_least64_t} \\ -\tcode{atomic_uint_least64_t} & \tcode{uint_least64_t} \\ -\tcode{atomic_int_fast8_t} & \tcode{int_fast8_t} \\ -\tcode{atomic_uint_fast8_t} & \tcode{uint_fast8_t} \\ -\tcode{atomic_int_fast16_t} & \tcode{int_fast16_t} \\ -\tcode{atomic_uint_fast16_t} & \tcode{uint_fast16_t} \\ -\tcode{atomic_int_fast32_t} & \tcode{int_fast32_t} \\ -\tcode{atomic_uint_fast32_t} & \tcode{uint_fast32_t} \\ -\tcode{atomic_int_fast64_t} & \tcode{int_fast64_t} \\ -\tcode{atomic_uint_fast64_t} & \tcode{uint_fast64_t} \\ -\tcode{atomic_intptr_t} & \tcode{intptr_t} \\ -\tcode{atomic_uintptr_t} & \tcode{uintptr_t} \\ -\tcode{atomic_size_t} & \tcode{size_t} \\ -\tcode{atomic_ptrdiff_t} & \tcode{ptrdiff_t} \\ -\tcode{atomic_intmax_t} & \tcode{intmax_t} \\ -\tcode{atomic_uintmax_t} & \tcode{uintmax_t} \\ -\hline -\end{floattablebase} +The specialization \tcode{atomic} is a standard-layout struct. \pnum \begin{note} The representation of an atomic specialization need not have the same size as its corresponding argument type. Specializations should have the same size whenever possible, as -this reduces the effort required to port existing code. \end{note} - -\rSec1[atomics.types.operations]{Operations on atomic types} - -\rSec2[atomics.types.operations.general]{General operations on atomic types} - -\pnum -The implementation shall provide the functions and function templates identified as ``general operations -on atomic types'' in~\ref{atomics.syn}. - -\pnum -In the declarations of these functions and function templates, the name -\tcode{\placeholder{atomic-type}} refers to either \tcode{atomic} or to a named base class for \tcode{T} -from Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. - -\rSec2[atomics.types.operations.templ]{Templated operations on atomic types} - -\pnum -The implementation shall declare but not define the -function templates identified as ``templated operations on atomic types'' in~\ref{atomics.syn}. - -\rSec2[atomics.types.operations.arith]{Arithmetic operations on atomic types} - -\pnum -The implementation shall provide the functions and function template specializations identified as ``arithmetic operations -on atomic types'' in~\ref{atomics.syn}. - -\indexlibrary{\idxcode{atomic<\placeholder{integral}>}}% -\pnum -In the declarations of these functions and function template specializations, -the name \tcode{\placeholder{integral}} refers to an -integral type and the name \tcode{\placeholder{atomic-integral}} refers to either -\tcode{atomic<\placeholder{integral}>} or to a named base class for \tcode{\placeholder{integral}} from -Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. - -\rSec2[atomics.types.operations.pointer]{Operations on atomic pointer types} -\indexlibrary{\idxcode{atomic}}% - -\pnum -The implementation shall provide the function templates identified as -``non-member overloads for atomic'' in~\ref{atomics.syn}. - -\rSec2[atomics.types.operations.req]{Requirements for operations on atomic types} - -\pnum -There are only a few kinds of operations on atomic types, though there are many -instances on those kinds. This section specifies each general kind. The specific -instances are defined in -\ref{atomics.types.generic}, \ref{atomics.types.operations.general}, -\ref{atomics.types.operations.arith}, and \ref{atomics.types.operations.pointer}. - -\pnum -In the following operation definitions: +this reduces the effort required to port existing code. \end{note} -\begin{itemize} -\item an \placeholder{A} refers to one of the atomic types. -\item a \placeholder{C} refers to its corresponding non-atomic type. -\item an \placeholder{M} refers to type of the other argument for arithmetic operations. For -integral atomic types, \placeholder{M} is \placeholder{C}. For atomic address types, \placeholder{M} is -\tcode{ptrdiff_t}. -\item the non-member functions not ending in \tcode{_explicit} have the semantics of their -corresponding \tcode{_explicit} functions with \tcode{memory_order} arguments of -\tcode{memory_order_seq_cst}. -\end{itemize} +\rSec2[atomics.types.operations]{Operations on atomic types} \pnum \begin{note} Many operations are volatile-qualified. The ``volatile as device register'' semantics have not changed in the standard. This qualification means that volatility is preserved when applying these operations to volatile objects. It does not mean that -operations on non-volatile objects become volatile. Thus, volatile qualified operations -on non-volatile objects may be merged under some conditions. \end{note} +operations on non-volatile objects become volatile. \end{note} \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}% \begin{itemdecl} -@\placeholdernc{A}@::@\placeholdernc{A}@() noexcept = default; +atomic() noexcept = default; \end{itemdecl} \begin{itemdescr} @@ -850,7 +622,7 @@ \indexlibrary{\idxcode{atomic}!constructor}% \indexlibrary{\idxcode{atomic<\placeholder{integral}>}!constructor}% \begin{itemdecl} -constexpr @\placeholdernc{A}@::@\placeholdernc{A}@(@\placeholdernc{C}@ desired) noexcept; +constexpr atomic(T desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -907,10 +679,8 @@ \indexlibrarymember{is_lock_free}{atomic}% \indexlibrarymember{is_lock_free}{atomic<\placeholder{integral}>}% \begin{itemdecl} -bool atomic_is_lock_free(const volatile @\placeholder{A}@*@\itcorr[-1]@ object) noexcept; -bool atomic_is_lock_free(const @\placeholder{A}@*@\itcorr[-1]@ object) noexcept; -bool @\placeholdernc{A}@::is_lock_free() const volatile noexcept; -bool @\placeholdernc{A}@::is_lock_free() const noexcept; +bool is_lock_free() const volatile noexcept; +bool is_lock_free() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -922,39 +692,14 @@ \end{note} \end{itemdescr} -\indexlibrary{\idxcode{atomic_init}}% -\begin{itemdecl} -void atomic_init(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -void atomic_init(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Non-atomically -initializes \tcode{*object} with value \tcode{desired}. This function shall only be applied -to objects that have been default constructed, and then only once. -\begin{note} -These semantics ensure compatibility with C. -\end{note} -\begin{note} -Concurrent access from another thread, even via an atomic operation, constitutes -a data race. -\end{note} - -\end{itemdescr} - \indexlibrary{\idxcode{atomic_store}}% \indexlibrary{\idxcode{atomic_store_explicit}}% \indexlibrarymember{store}{atomic}% \indexlibrarymember{store}{atomic}% \indexlibrarymember{store}{atomic<\placeholder{integral}>}% \begin{itemdecl} -void atomic_store(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -void atomic_store(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -void atomic_store_explicit(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired, memory_order order) noexcept; -void atomic_store_explicit(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired, memory_order order) noexcept; -void @\placeholdernc{A}@::store(@\placeholdernc{C}@ desired, memory_order order = memory_order_seq_cst) volatile noexcept; -void @\placeholdernc{A}@::store(@\placeholdernc{C}@ 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} @@ -963,7 +708,7 @@ \tcode{memory_order_acquire}, nor \tcode{memory_order_acq_rel}. \pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by \tcode{this} +\effects Atomically replaces the value pointed to by \tcode{this} with the value of \tcode{desired}. Memory is affected according to the value of \tcode{order}. \end{itemdescr} @@ -972,13 +717,13 @@ \indexlibrarymember{operator=}{atomic}% \indexlibrarymember{operator=}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator=(@\placeholdernc{C}@ desired) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator=(@\placeholdernc{C}@ desired) noexcept; +T operator=(T desired) volatile noexcept; +T operator=(T desired) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{store(desired)}. +\effects Equivalent to: \tcode{store(desired)}. \pnum \returns \tcode{desired}. @@ -990,12 +735,8 @@ \indexlibrarymember{load}{atomic}% \indexlibrarymember{load}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ atomic_load(const volatile @\placeholder{A}@*@\itcorr[-1]@ object) noexcept; -@\placeholdernc{C}@ atomic_load(const @\placeholder{A}@*@\itcorr[-1]@ object) noexcept; -@\placeholdernc{C}@ atomic_load_explicit(const volatile @\placeholder{A}@*@\itcorr[-1]@ object, memory_order) noexcept; -@\placeholdernc{C}@ atomic_load_explicit(const @\placeholder{A}@*@\itcorr[-1]@ object, memory_order) noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::load(memory_order order = memory_order_seq_cst) const volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::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} @@ -1006,23 +747,20 @@ \effects Memory is affected according to the value of \tcode{order}. \pnum -\returns Atomically returns the value pointed to by \tcode{object} or by \tcode{this}. +\returns Atomically returns the value pointed to by \tcode{this}. \end{itemdescr} \indexlibrarymember{operator \placeholder{type}}{atomic}% \indexlibrarymember{operator T*}{atomic}% \indexlibrarymember{operator \placeholder{integral}}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{A}@::operator @\placeholder{C}@() const volatile noexcept; -@\placeholdernc{A}@::operator @\placeholder{C}@() const noexcept; +operator T() const volatile noexcept; +operator T() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{load()}. - -\pnum -\returns The result of \tcode{load()}. +\effects Equivalent to: \tcode{return load();} \end{itemdescr} @@ -1032,23 +770,19 @@ \indexlibrarymember{exchange}{atomic}% \indexlibrarymember{exchange}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ atomic_exchange(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -@\placeholdernc{C}@ atomic_exchange(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired) noexcept; -@\placeholdernc{C}@ atomic_exchange_explicit(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired, memory_order) noexcept; -@\placeholdernc{C}@ atomic_exchange_explicit(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{C}@ desired, memory_order) noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::exchange(@\placeholdernc{C}@ desired, memory_order order = memory_order_seq_cst) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::exchange(@\placeholdernc{C}@ 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} \pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by \tcode{this} +\effects Atomically replaces the value pointed to by \tcode{this} with \tcode{desired}. Memory is affected according to the value of \tcode{order}. These operations are atomic read-modify-write operations~(\ref{intro.multithread}). \pnum -\returns Atomically returns the value pointed to by \tcode{object} or by \tcode{this} immediately before the effects. +\returns Atomically returns the value pointed to by \tcode{this} immediately before the effects. \end{itemdescr} \indexlibrary{\idxcode{atomic_compare_exchange_weak}}% @@ -1062,34 +796,22 @@ \indexlibrarymember{compare_exchange_strong}{atomic}% \indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{integral}>}% \begin{itemdecl} -bool atomic_compare_exchange_weak(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired) noexcept; -bool atomic_compare_exchange_weak(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired) noexcept; -bool atomic_compare_exchange_strong(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired) noexcept; -bool atomic_compare_exchange_strong(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired) noexcept; -bool atomic_compare_exchange_weak_explicit(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_weak_explicit(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_strong_explicit(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_strong_explicit(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholder{C}@*@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\placeholdernc{A}@::compare_exchange_weak(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) volatile noexcept; -bool @\placeholdernc{A}@::compare_exchange_weak(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\placeholdernc{A}@::compare_exchange_strong(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) volatile noexcept; -bool @\placeholdernc{A}@::compare_exchange_strong(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\placeholdernc{A}@::compare_exchange_weak(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order order = memory_order_seq_cst) volatile noexcept; -bool @\placeholdernc{A}@::compare_exchange_weak(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order order = memory_order_seq_cst) noexcept; -bool @\placeholdernc{A}@::compare_exchange_strong(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order order = memory_order_seq_cst) volatile noexcept; -bool @\placeholdernc{A}@::compare_exchange_strong(@\placeholder{C}@&@\itcorr[-1]@ expected, @\placeholdernc{C}@ desired, - memory_order order = memory_order_seq_cst) noexcept; +bool compare_exchange_weak(T& expected, T desired, + memory_order success, memory_order failure) volatile noexcept; +bool compare_exchange_weak(T& expected, T desired, + memory_order success, memory_order failure) noexcept; +bool compare_exchange_strong(T& expected, T desired, + memory_order success, memory_order failure) volatile noexcept; +bool compare_exchange_strong(T& expected, T desired, + memory_order success, memory_order failure) noexcept; +bool compare_exchange_weak(T& expected, T desired, + 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; +bool compare_exchange_strong(T& expected, T desired, + memory_order order = memory_order_seq_cst) volatile noexcept; +bool compare_exchange_strong(T& expected, T desired, + memory_order order = memory_order_seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -1099,10 +821,10 @@ \pnum \effects Retrieves the value in \tcode{expected}. It then atomically -compares the contents of the memory pointed to by \tcode{object} or by \tcode{this} +compares the contents of the memory pointed to by \tcode{this} for equality with that previously retrieved from \tcode{expected}, and if true, replaces the contents of the memory pointed to -by \tcode{object} or by \tcode{this} with that in \tcode{desired}. +by \tcode{this} with that in \tcode{desired}. If and only if the comparison is true, memory is affected according to the value of \tcode{success}, and if the comparison is false, memory is affected according to the value of \tcode{failure}. When only one \tcode{memory_order} argument is @@ -1113,11 +835,11 @@ \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 \tcode{object} or by \tcode{this} during the atomic comparison. +read from the memory pointed to by \tcode{this} during the atomic comparison. If the operation returns \tcode{true}, these operations are atomic read-modify-write operations~(\ref{intro.multithread}) on the memory -pointed to by \tcode{this} or \tcode{object}. +pointed to by \tcode{this}. Otherwise, these operations are atomic load operations on that memory. \pnum @@ -1125,12 +847,12 @@ \pnum \begin{note} For example, the effect of -\tcode{atomic_compare_exchange_strong} is +\tcode{compare_exchange_strong} is \begin{codeblock} -if (memcmp(object, expected, sizeof(*object)) == 0) - memcpy(object, &desired, sizeof(*object)); +if (memcmp(this, &expected, sizeof(*this)) == 0) + memcpy(this, &desired, sizeof(*this)); else - memcpy(expected, object, sizeof(*object)); + memcpy(expected, this, sizeof(*this)); \end{codeblock} \end{note} \begin{example} The expected use of the compare-and-exchange operations is as follows. The @@ -1163,7 +885,7 @@ \pnum \remarks A weak compare-and-exchange operation may fail spuriously. That is, even when -the contents of memory referred to by \tcode{expected} and \tcode{object} are +the contents of memory referred to by \tcode{expected} and \tcode{this} are equal, it may return \tcode{false} and store back to \tcode{expected} the same memory contents that were originally there. \begin{note} This @@ -1186,18 +908,127 @@ rapidly. \end{note} \end{itemdescr} +\rSec2[atomics.types.int]{Specializations for integers} + +\indexlibrary{\idxcode{atomic<\placeholder{integral}>}}% +\pnum +There are specializations of the \tcode{atomic} +template for the integral types +\tcode{char}, +\tcode{signed char}, +\tcode{unsigned char}, +\tcode{short}, +\tcode{unsigned short}, +\tcode{int}, +\tcode{unsigned int}, +\tcode{long}, +\tcode{unsigned long}, +\tcode{long long}, +\tcode{unsigned long long}, +\tcode{char16_t}, +\tcode{char32_t}, +\tcode{wchar_t}, +and any other types needed by the typedefs in the header \tcode{}. +For each such integral type \tcode{\placeholder{integral}}, the specialization +\tcode{atomic<\placeholder{integral}>} provides additional atomic operations appropriate to integral types. +\begin{note} +For the specialization \tcode{atomic}, see \ref{atomics.types.generic}. +\end{note} + +\begin{codeblock} +namespace std { + 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; + 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; + bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, + memory_order, memory_order) volatile noexcept; + bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, + memory_order, memory_order) noexcept; + bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholdernc{integral}@, + memory_order, memory_order) volatile noexcept; + 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; + bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholdernc{integral}@, + 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; + + atomic() noexcept = default; + constexpr atomic(@\placeholdernc{integral}@) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + @\placeholdernc{integral}@ operator=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator=(@\placeholdernc{integral}@) noexcept; + + @\placeholdernc{integral}@ operator++(int) volatile noexcept; + @\placeholdernc{integral}@ operator++(int) noexcept; + @\placeholdernc{integral}@ operator--(int) volatile noexcept; + @\placeholdernc{integral}@ operator--(int) noexcept; + @\placeholdernc{integral}@ operator++() volatile noexcept; + @\placeholdernc{integral}@ operator++() noexcept; + @\placeholdernc{integral}@ operator--() volatile noexcept; + @\placeholdernc{integral}@ operator--() noexcept; + @\placeholdernc{integral}@ operator+=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator+=(@\placeholdernc{integral}@) noexcept; + @\placeholdernc{integral}@ operator-=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator-=(@\placeholdernc{integral}@) noexcept; + @\placeholdernc{integral}@ operator&=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator&=(@\placeholdernc{integral}@) noexcept; + @\placeholdernc{integral}@ operator|=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator|=(@\placeholdernc{integral}@) noexcept; + @\placeholdernc{integral}@ operator^=(@\placeholdernc{integral}@) volatile noexcept; + @\placeholdernc{integral}@ operator^=(@\placeholdernc{integral}@) noexcept; + }; +} +\end{codeblock} + +\pnum +The atomic integral 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 computations. The key, operator, and computation correspondence is: \begin{floattable} {Atomic arithmetic computations}{tab:atomic.arithmetic.computations}{lll|lll} \hline -\tcode{Key} & - Op & - Computation & -\tcode{Key} & - Op & - Computation \\ \hline +\hdstyle{\tcode{\placeholder{key}}} & + \hdstyle{Op} & + \hdstyle{Computation} & +\hdstyle{\tcode{\placeholder{key}}} & + \hdstyle{Op} & + \hdstyle{Computation} \\ \hline \tcode{add} & \tcode{+} & addition & @@ -1225,38 +1056,31 @@ \indexlibrary{\idxcode{atomic_fetch_or_explicit}}% \indexlibrary{\idxcode{atomic_fetch_sub_explicit}}% \indexlibrary{\idxcode{atomic_fetch_xor_explicit}}% -\indexlibrarymember{fetch_add}{atomic}% -\indexlibrarymember{fetch_sub}{atomic}% \indexlibrarymember{fetch_add}{atomic<\placeholder{integral}>}% \indexlibrarymember{fetch_and}{atomic<\placeholder{integral}>}% \indexlibrarymember{fetch_or}{atomic<\placeholder{integral}>}% \indexlibrarymember{fetch_sub}{atomic<\placeholder{integral}>}% \indexlibrarymember{fetch_xor}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ atomic_fetch_@\placeholdernc{key}@(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{M}@ operand) noexcept; -@\placeholdernc{C}@ atomic_fetch_@\placeholdernc{key}@(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{M}@ operand) noexcept; -@\placeholdernc{C}@ atomic_fetch_@\placeholdernc{key}@_explicit(volatile @\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{M}@ operand, memory_order order) noexcept; -@\placeholdernc{C}@ atomic_fetch_@\placeholdernc{key}@_explicit(@\placeholder{A}@*@\itcorr[-1]@ object, @\placeholdernc{M}@ operand, memory_order order) noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::fetch_@\placeholdernc{key}@(@\placeholdernc{M}@ operand, memory_order order = memory_order_seq_cst) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::fetch_@\placeholdernc{key}@(@\placeholdernc{M}@ 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} \pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by +\effects Atomically replaces the value pointed to by \tcode{this} with the result of the computation applied to the -value pointed to by \tcode{object} or by \tcode{this} and the given \tcode{operand}. +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~(\ref{intro.multithread}). \pnum -\returns Atomically, the value pointed to by \tcode{object} or by \tcode{this} immediately before the effects. +\returns Atomically, the value pointed to by \tcode{this} immediately before the effects. \pnum \indextext{signed integer representation!two's complement}% -\remarks For signed integer types, arithmetic is defined to use two's complement -representation. There are no undefined results. For address types, the result may be an -undefined address, but the operations otherwise have no undefined behavior. +\remarks For signed integer types, arithmetic is defined to use two's complement representation. +There are no undefined results. \end{itemdescr} \indexlibrarymember{operator+=}{atomic}% @@ -1265,74 +1089,235 @@ \indexlibrarymember{operator-=}{atomic<\placeholder{integral}>}% \indexlibrarymember{operator\&=}{atomic<\placeholder{integral}>}% \indexlibrarymember{operator"|=}{atomic<\placeholder{integral}>}% -\indexlibrarymember{operator\^{}=}{atomic<\placeholder{integral}>}% +\indexlibrarymember{operator\caret=}{atomic<\placeholder{integral}>}% +\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;} +\end{itemdescr} + +\rSec2[atomics.types.pointer]{Partial specialization for pointers} +\indexlibrary{\idxcode{atomic}}% + +\begin{codeblock} +namespace std { + 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; + operator T*() const volatile noexcept; + operator T*() const noexcept; + T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept; + T* exchange(T*, memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; + bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; + bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; + bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; + bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept; + T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; + T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; + T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; + T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(T*) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + T* operator=(T*) volatile noexcept; + T* operator=(T*) noexcept; + + T* operator++(int) volatile noexcept; + T* operator++(int) noexcept; + T* operator--(int) volatile noexcept; + T* operator--(int) noexcept; + T* operator++() volatile noexcept; + T* operator++() noexcept; + T* operator--() volatile noexcept; + T* operator--() noexcept; + T* operator+=(ptrdiff_t) volatile noexcept; + T* operator+=(ptrdiff_t) noexcept; + T* operator-=(ptrdiff_t) volatile noexcept; + T* operator-=(ptrdiff_t) noexcept; + }; +} +\end{codeblock} + +\indexlibrary{\idxcode{atomic}}% +\pnum +There is a partial specialization of the \tcode{atomic} class template for pointers. +Specializations of this partial specialization 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 pointer arithmetic. The key, operator, +and computation correspondence is: + +\begin{floattable} +{Atomic pointer computations}{tab:atomic.pointer.computations}{lll|lll} +\hline +\tcode{Key} & + Op & + Computation & +\tcode{Key} & + Op & + Computation \\ \hline +\tcode{add} & + \tcode{+} & + addition & +\tcode{sub} & + \tcode{-} & + subtraction \\ \hline +\end{floattable} + +\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}% +\indexlibrarymember{fetch_sub}{atomic}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator @\placeholder{op}@=(@\placeholdernc{M}@ operand) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator @\placeholder{op}@=(@\placeholdernc{M}@ operand) 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} \pnum -\effects As if by \tcode{fetch_\placeholder{key}(operand)}. +\requires T shall be an object type, otherwise the program is ill-formed. +\begin{note} Pointer arithmetic on \tcode{void*} or function pointers is ill-formed. \end{note} + +\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~(\ref{intro.multithread}). + +\pnum +\returns Atomically, the value pointed to by \tcode{this} immediately before the effects. + +\pnum +\remarks The result may be an undefined address, +but the operations otherwise have no undefined behavior. +\end{itemdescr} + +\indexlibrarymember{operator+=}{atomic}% +\indexlibrarymember{operator-=}{atomic}% +\begin{itemdecl} +T* operator @\placeholder{op}@=(ptrdiff_t operand) volatile noexcept; +T* operator @\placeholder{op}@=(ptrdiff_t operand) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{fetch_\placeholder{key}(operand) op operand}. +\effects Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;} \end{itemdescr} +\rSec2[atomics.types.memop]{Member operators common to integers and pointers to objects} + \indexlibrarymember{operator++}{atomic}% \indexlibrarymember{operator++}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator++(int) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator++(int) noexcept; +T operator++(int) volatile noexcept; +T operator++(int) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum -\returns \tcode{fetch_add(1)}. +\effects Equivalent to: \tcode{return fetch\_add(1);} \end{itemdescr} \indexlibrarymember{operator\dcr}{atomic}% \indexlibrarymember{operator\dcr}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator--(int) volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator--(int) noexcept; +T operator--(int) volatile noexcept; +T operator--(int) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum -\returns \tcode{fetch_sub(1)}. +\effects Equivalent to: \tcode{return fetch\_sub(1);} \end{itemdescr} \indexlibrarymember{operator++}{atomic}% \indexlibrarymember{operator++}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator++() volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator++() noexcept; +T operator++() volatile noexcept; +T operator++() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{fetch_add(1)}. - -\pnum -\returns \tcode{fetch_add(1) + 1}. +\effects Equivalent to: \tcode{return fetch_add(1) + 1;} \end{itemdescr} \indexlibrarymember{operator\dcr}{atomic}% \indexlibrarymember{operator\dcr}{atomic<\placeholder{integral}>}% \begin{itemdecl} -@\placeholdernc{C}@ @\placeholdernc{A}@::operator--() volatile noexcept; -@\placeholdernc{C}@ @\placeholdernc{A}@::operator--() noexcept; +T operator--() volatile noexcept; +T operator--() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects As if by \tcode{fetch_sub(1)}. +\effects Equivalent to: \tcode{return fetch_sub(1) - 1;} +\end{itemdescr} + + +\rSec1[atomics.nonmembers]{Non-member functions} + +\pnum +A non-member function template whose name matches the pattern +\tcode{atomic_\placeholder{f}} or the pattern \tcode{atomic_\placeholder{f}_explicit} +invokes the member function \tcode{\placeholder{f}}, with the value of the +first parameter as the object expression and the values of the remaining parameters +(if any) as the arguments of the member function call, in order. An argument +for a parameter of type \tcode{atomic::value_type*} is dereferenced when +passed to the member function call. +If no such member function exists, the program is ill-formed. + +\indexlibrary{\idxcode{atomic_init}}% +\begin{itemdecl} +template + void atomic_init(volatile atomic* object, typename atomic::value_type desired) noexcept; +template + void atomic_init(atomic* object, typename atomic::value_type desired) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{fetch_sub(1) - 1}. +\effects Non-atomically +initializes \tcode{*object} with value \tcode{desired}. This function shall only be applied +to objects that have been default constructed, and then only once. +\begin{note} +These semantics ensure compatibility with C. +\end{note} +\begin{note} +Concurrent access from another thread, even via an atomic operation, constitutes +a data race. +\end{note} \end{itemdescr} +\pnum +\begin{note} +The non-member functions enable programmers to write code that can be +compiled as either C or C++, for example in a shared header file. +\end{note} + \rSec1[atomics.flag]{Flag type and operations} \begin{codeblock} @@ -1367,14 +1352,11 @@ \pnum Operations on an object of type \tcode{atomic_flag} shall be lock-free. \begin{note} Hence -the operations should also be address-free. No other type requires lock-free operations, -so the \tcode{atomic_flag} type is the minimum hardware-implemented type needed to -conform to this International Standard. The remaining types can be emulated with -\tcode{atomic_flag}, though with less than ideal properties. \end{note} +the operations should also be address-free. \end{note} \pnum -The \tcode{atomic_flag} type shall be a standard-layout struct. -It shall have a trivial default constructor, a deleted copy constructor, a deleted copy assignment operator, and a trivial destructor. +The \tcode{atomic_flag} type is a standard-layout struct. +It has a trivial default constructor and a trivial destructor. \pnum The macro \tcode{ATOMIC_FLAG_INIT} shall be defined in such a way that it can be used to initialize an object of type \tcode{atomic_flag} to the diff --git a/source/back.tex b/source/back.tex index 5ccf25bbfe..3ac2a093d3 100644 --- a/source/back.tex +++ b/source/back.tex @@ -1,16 +1,39 @@ %!TEX root = std.tex +% FIXME: For unknown reasons, hanging paragraphs are not indented within our +% glossaries by default. +\let\realglossitem\glossitem +\renewcommand{\glossitem}[4]{\hangpara{4em}{1}\realglossitem{#1}{#2}{#3}{#4}} + \clearpage \renewcommand{\glossaryname}{Cross references} \renewcommand{\preglossaryhook}{This annex lists each section label and the corresponding section number and page number, in alphabetical order by label.\\} \twocolglossary \renewcommand{\leftmark}{\glossaryname} +{ +\raggedright \printglossary[xrefindex] +} + +\clearpage +\input{xrefdelta} +\renewcommand{\glossaryname}{Cross references from ISO \CppXIV} +\renewcommand{\preglossaryhook}{All section labels from +ISO \CppXIV (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp}) +are present in this document, with the exceptions described below.\\} +\renewcommand{\leftmark}{\glossaryname} +{ +\raggedright +\printglossary[xrefdelta] +} \clearpage \renewcommand{\leftmark}{\indexname} +{ +\raggedright \printindex[generalindex] +} \clearpage \renewcommand{\indexname}{Index of grammar productions} @@ -18,17 +41,26 @@ general text where the grammar production is defined. The second page number is the corresponding page in the Grammar summary (Annex~\ref{gram}).\\} \renewcommand{\leftmark}{\indexname} +{ +\raggedright \printindex[grammarindex] +} \clearpage \renewcommand{\preindexhook}{} \renewcommand{\indexname}{Index of library names} \renewcommand{\leftmark}{\indexname} +{ +\raggedright \printindex[libraryindex] +} \clearpage \renewcommand{\preindexhook}{The entries in this section are rough descriptions; exact specifications are at the indicated page in the general text.\\} \renewcommand{\indexname}{Index of implementation-defined behavior} \renewcommand{\leftmark}{\indexname} +{ +\raggedright \printindex[impldefindex] +} diff --git a/source/basic.tex b/source/basic.tex index 1692459c63..96c2128196 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -37,7 +37,7 @@ \grammarterm{literal-operator-id}~(\ref{over.literal}), \grammarterm{conversion-function-id}~(\ref{class.conv.fct}), or \grammarterm{template-id}~(\ref{temp.names}) that denotes an entity or -\grammarterm{label}~(\ref{stmt.goto}, \ref{stmt.label}). +label~(\ref{stmt.goto}, \ref{stmt.label}). \pnum Every name that denotes an entity is introduced by a @@ -119,7 +119,7 @@ (\ref{dcl.link}) and neither an \grammarterm{initializer} nor a \grammarterm{function-body}, \item -\indextext{declaration!\idxcode{static member}}% +\indextext{declaration!static member@\tcode{static} member}% it declares a non-inline static data member in a class definition (\ref{class.mem},~\ref{class.static}), \item @@ -474,7 +474,7 @@ were present in the definition of \tcode{D}; that is, the default argument is subject to the requirements described in this paragraph (and, if the default argument has subexpressions with default arguments, this -requirement applies recursively).\footnote{\ref{dcl.fct.default} +requirement applies recursively).\footnote{\ref{dcl.fct.default} describes how default argument names are looked up.} \item if \tcode{D} is a class with an implicitly-declared @@ -764,7 +764,7 @@ \pnum \indextext{parameter!scope of}% The potential scope of a function parameter name -(including one appearing in a +(including one appearing in a \grammarterm{lambda-declarator}) or of a function-local predefined variable in a function @@ -883,7 +883,7 @@ only of the declarative region following the name's point of declaration, but also of all function bodies, default arguments, \grammarterm{noexcept-specifier}{s}, and -\grammarterm{brace-or-equal-initializers} of non-static data members +\grammarterm{brace-or-equal-initializer}{s} of non-static data members in that class (including such things in nested classes). @@ -1084,14 +1084,15 @@ \pnum The name lookup rules apply uniformly to all names (including \grammarterm{typedef-name}{s}~(\ref{dcl.typedef}), -\grammarterm{namespace-name}{s}~(\ref{basic.namespace}), and +\grammarterm{namespace-name}{s} (\ref{basic.namespace}), and \grammarterm{class-name}{s}~(\ref{class.name})) wherever the grammar allows such names in the context discussed by a particular rule. Name lookup -associates the use of a name with a declaration~(\ref{basic.def}) of -that name. Name lookup shall find an unambiguous declaration for the -name (see~\ref{class.member.lookup}). Name lookup may associate more -than one declaration with a name if it finds the name to be a function -name; the declarations are said to form a set of overloaded +associates the use of a name with a set of declarations~(\ref{basic.def}) of +that name. +The declarations found by name lookup shall either all declare the same entity or +shall all declare functions; +in the latter case, +the declarations are said to form a set of overloaded functions~(\ref{over.load}). Overload resolution~(\ref{over.match}) takes place after name lookup has succeeded. The access rules (Clause~\ref{class.access}) are considered only once name lookup and @@ -1778,7 +1779,7 @@ declarations of \tcode{m} in \tcode{X} and the inline namespace set of \tcode{X}~(\ref{namespace.def}). If $S'(X, m)$ is not empty, $S(X, m)$ is $S'(X, m)$; otherwise, $S(X, m)$ is the union of $S(N_i, m)$ for -all namespaces $N_i$ nominated by \grammarterm{using-directives} in +all namespaces $N_i$ nominated by \grammarterm{using-directive}{s} in \tcode{X} and its inline namespace set. \pnum @@ -2209,17 +2210,17 @@ object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope: \begin{itemize} -\item When a name has \defn{external linkage}\indextext{linkage!external}, +\item When a name has \indextext{linkage!external}\defn{external linkage}, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit. -\item When a name has \defn{internal linkage}\indextext{linkage!internal}, +\item When a name has \indextext{linkage!internal}\defn{internal linkage}, the entity it denotes can be referred to by names from other scopes in the same translation unit. -\item When a name has \defn{no linkage}\indextext{linkage!no}, the entity it denotes +\item When a name has \indextext{linkage!no}\defn{no linkage}, the entity it denotes cannot be referred to by names from other scopes. \end{itemize} @@ -2261,7 +2262,6 @@ a named enumeration~(\ref{dcl.enum}), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes~(\ref{dcl.typedef}); or -\item an enumerator belonging to an enumeration with linkage; or \item a template. \end{itemize} @@ -2280,27 +2280,28 @@ outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching -entity is found, the block scope entity receives external linkage. \begin{example} - +entity is found, the block scope entity receives external linkage. +If, within a translation unit, the same entity is declared with both +internal and external linkage, the program is ill-formed. +\begin{example} \begin{codeblock} static void f(); static int i = 0; // \#1 void g() { extern void f(); // internal linkage - int i; // \#2 \tcode{i} has no linkage + int i; // \#2: \tcode{i} has no linkage { extern void f(); // internal linkage - extern int i; // \#3 external linkage + extern int i; // \#3: external linkage, ill-formed } } \end{codeblock} -There are three objects named \tcode{i} in this program. The object with -internal linkage introduced by the declaration in global scope (line -\#1), the object with automatic storage duration and no linkage -introduced by the declaration on line \#2, and the object with -static storage duration and external linkage introduced by the -declaration on line \#3. \end{example} +Without the declaration at line \#2, +the declaration at line \#3 would link with the declaration at line \#1. +Because the declaration with internal linkage is hidden, however, +\#3 is given external linkage, making the program ill-formed. +\end{example} \pnum When a block scope declaration of an entity with linkage is not found to @@ -2394,7 +2395,7 @@ \pnum Two names that are the same (Clause~\ref{basic}) and that are declared in different scopes shall denote the same variable, function, -type, enumerator, template or namespace if +type, template or namespace if \begin{itemize} \item both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and @@ -2432,8 +2433,12 @@ \pnum \indextext{program!start|(}% -A program shall contain a global function called \tcode{main}, which is the designated -start of the program. It is \impldef{defining \tcode{main} in freestanding environment} +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~(\ref{basic.start.static}) and destroyed~(\ref{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 @@ -2525,32 +2530,17 @@ Within each of these phases of initiation, initialization occurs as follows. \pnum -\indextext{initialization!\idxcode{static object}}% +\indextext{initialization!static object@\tcode{static} object}% \indextext{initialization!constant}% -A \defn{constant initializer} for an object \tcode{o} is an expression that is a -constant expression, except that it may also invoke constexpr constructors +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: -\begin{itemize} -\item -if each full-expression (including implicit conversions) that appears in -the initializer of a reference with static or thread storage duration is a -constant expression~(\ref{expr.const}) and the reference is bound to a glvalue -designating an object with static storage duration, to a temporary object -(see~\ref{class.temporary}) or subobject thereof, or to a function; - -\item -if an object with static or thread storage duration is initialized -by a constructor call, and if the initialization full-expression is a constant -initializer for the object; - -\item -if an object with static or thread storage duration is not initialized by a constructor call -and if either the object is value-initialized or every full-expression that -appears in its initializer is a constant expression. -\end{itemize} - +\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~(\ref{basic.stc.static}) or thread storage @@ -2559,7 +2549,8 @@ \indextext{initialization!dynamic}% \defn{static initialization}; all other initialization is \defn{dynamic initialization}. -Static initialization shall be performed before any dynamic initialization takes place. +All static initialization strongly happens before~(\ref{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} @@ -2625,14 +2616,28 @@ \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, the initialization of -\tcode{V} is sequenced before the initialization of \tcode{W} if the -program does not start a thread (\ref{intro.multithread}) and otherwise -happens before the initialization of \tcode{W}. +every translation unit in which \tcode{W} is defined, then +\begin{itemize} +\item +if the program starts a thread~(\ref{intro.multithread}) +other than the main thread~(\ref{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} \item -Otherwise, if a program starts a thread before either \tcode{V} or \tcode{W} is -initialized, the initializations of \tcode{V} and \tcode{W} are unsequenced. +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. @@ -2642,18 +2647,31 @@ ordered variables concurrently with another sequence. \end{note} +\pnum +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% +A \defnx{non-initialization odr-use}{odr-use!non-initialization} +is an odr-use~(\ref{basic.def.odr}) not caused directly or indirectly by +the initialization of a non-local static or thread storage duration variable. + \pnum \indextext{evaluation!unspecified order of}% -It is \impldef{dynamic initialization of static variables before \tcode{main}} whether the -dynamic initialization of a non-local non-inline variable with static storage duration -happens before the first statement of \tcode{main}. If the initialization is deferred to -happen after the first statement of \tcode{main}, it happens before the -first odr-use~(\ref{basic.def.odr}) 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 +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 must be initialized even if it is not -odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} +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} \begin{example} \begin{codeblock} // - File 1 - @@ -2694,21 +2712,26 @@ \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 happens before the -first statement of \tcode{main}. If the initialization is deferred -to happen after the first statement of \tcode{main}, it happens before -the first odr-use~(\ref{basic.def.odr}) of that variable. +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 static -or thread storage duration is sequenced before -the first statement of the initial function of the thread. -If the initialization is deferred to some point in time sequenced after -the first statement of the initial function of the thread, -it is sequenced before the first odr-use~(\ref{basic.def.odr}) -of any non-inline variable with thread storage duration defined -in the same translation unit as the variable to be initialized. +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 @@ -2724,24 +2747,34 @@ \indextext{\idxcode{main} function!return from}% Destructors~(\ref{class.dtor}) for initialized objects (that is, objects whose lifetime~(\ref{basic.life}) has begun) -with static storage duration -are called as a result of returning from \tcode{main} and as a result of calling +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}~(\ref{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}~(\ref{basic.start.main}). +\end{note} + +\pnum Destructors for initialized objects with thread storage duration within a given thread are called as a result of returning from the initial function of that thread and as a result of that thread calling \tcode{std::exit}. The completions of the destructors for all initialized objects with thread storage -duration within that thread are sequenced before the initiation of the destructors of +duration within that thread strongly happen before the initiation of the destructors of any object with static storage duration. -If the completion of the constructor or dynamic initialization of an object with thread -storage duration is sequenced before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. + +\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. -\begin{note} This definition permits concurrent destruction. \end{note} If an object is +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 @@ -2763,13 +2796,13 @@ \indextext{\idxcode{atexit}}% \indexlibrary{\idxcode{atexit}}% If the completion of the initialization of an object with static storage -duration is sequenced before a call to \tcode{std::atexit}~(see +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} is sequenced before the completion of the initialization of +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} is sequenced before another call to \tcode{std::atexit}, the +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. @@ -2819,8 +2852,8 @@ Static, thread, and automatic storage durations are associated with objects introduced by declarations~(\ref{basic.def}) and implicitly created by the implementation~(\ref{class.temporary}). The dynamic storage duration -is associated with objects created with \tcode{operator} -\tcode{new}~(\ref{expr.new}). +is associated with objects created by a +\grammarterm{new-expression}~(\ref{expr.new}). \pnum The storage duration categories apply to references as well. @@ -2856,14 +2889,14 @@ eliminated as specified in~\ref{class.copy}. \pnum -\indextext{object!\idxcode{local static}}% +\indextext{object!local static@local \tcode{static}}% The keyword \tcode{static} can be used to declare a local variable with static storage duration. \begin{note} \ref{stmt.dcl} describes the initialization of local \tcode{static} variables; \ref{basic.start.term} describes the destruction of local \tcode{static} variables. \end{note} \pnum -\indextext{member!\idxcode{class static}}% +\indextext{member!class static@class \tcode{static}}% The keyword \tcode{static} applied to a class data member in a class definition gives the data member static storage duration. @@ -2956,8 +2989,8 @@ \tcode{op\-er\-a\-tor} \tcode{delete}, and \tcode{operator} \tcode{delete[]}. \begin{note} The implicit declarations do not introduce the names \tcode{std}, -\tcode{std\colcol{}size_t}, -\tcode{std\colcol{}align_val_t}, +\tcode{std::size_t}, +\tcode{std::align_val_t}, or any other names that the library uses to declare these names. Thus, a \grammarterm{new-expression}, \grammarterm{delete-expression} or function call that refers to one of @@ -3122,18 +3155,17 @@ \end{itemize} \pnum -\indextext{safely-derived pointer}% -A pointer value is a \grammarterm{safely-derived pointer} to a dynamic object only if it +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 -\tcode{::operator new(std\colcol{}size_t)} or -\tcode{::operator new(std\colcol{}size_t, std\colcol{}align_val_t)}% +\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 on indirection through pointers to memory not allocated by \tcode{::operator new}. This maintains the ability of many \Cpp implementations to use binary libraries and components written in other languages. In particular, this applies to C binaries, -because indirection through pointers to memory allocated by \tcode{std\colcol{}malloc} is not restricted.} +because indirection through pointers to memory allocated by \tcode{std::malloc} is not restricted.} \item the result of taking the address of an object (or one of its subobjects) designated by an lvalue resulting from indirection @@ -3157,9 +3189,8 @@ \pnum \indextext{integer representation}% -\indextext{safely-derived pointer!integer representation}% -\indextext{pointer, integer representation of safely-derived}% -An integer value is an \grammarterm{integer representation of a safely-derived pointer} +\indextext{pointer!integer representation of safely-derived}% +An integer value is an \defnx{integer representation of a safely-derived pointer}{safely-derived pointer!integer representation} only if its type is at least as large as \tcode{std::intptr_t} and it is one of the following: @@ -3296,8 +3327,10 @@ the pointer is used as the operand of a \tcode{static_cast}~(\ref{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 either \cv{}~\tcode{char} - or \cv{}~\tcode{unsigned char}, or + and subsequently to pointer to + \cv{}~\tcode{char}, + \cv{}~\tcode{unsigned char}, or + \cv{}~\tcode{std::byte}~(\ref{cstddef.syn}), or \item the pointer is used as the operand of a \tcode{dynamic_cast}~(\ref{expr.dynamic.cast}). @@ -3482,11 +3515,14 @@ For any object (other than a base-class subobject) of trivially copyable type \tcode{T}, whether or not the object holds a valid value of type \tcode{T}, the underlying bytes~(\ref{intro.memory}) making up the -object can be copied into an array of \tcode{char} or \tcode{unsigned} -\tcode{char}.\footnote{By using, for example, the library +object can be copied into an array of +\tcode{char}, +\tcode{unsigned char}, or +\tcode{std::byte}~(\ref{cstddef.syn}).% +\footnote{By using, for example, the library functions~(\ref{headers}) \tcode{std::memcpy} or \tcode{std::memmove}.} -If the content of the array of \tcode{char} or \tcode{unsigned} -\tcode{char} is copied back into the object, the object shall +If the content of that array +is copied back into the object, the object shall subsequently hold its original value. \begin{example} \begin{codeblock} #define N sizeof(T) @@ -3522,7 +3558,7 @@ The \defn{object representation} \indextext{representation!object}% of an object of type \tcode{T} is the -sequence of \placeholder{N} \tcode{unsigned} \tcode{char} objects taken up +sequence of \placeholder{N} \tcode{unsigned char} objects taken up by the object of type \tcode{T}, where \placeholder{N} equals \tcode{sizeof(T)}. The \indextext{representation!value}% @@ -3604,23 +3640,23 @@ types, pointer to member types~(\ref{basic.compound}), \tcode{std::nullptr_t}, and -cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called +cv-qualified~(\ref{basic.type.qualifier}) versions of these +types are collectively called \defnx{scalar types}{scalar type}. Scalar types, POD classes (Clause~\ref{class}), arrays of such types and cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called +types are collectively called \defnx{POD types}{type!POD}. Cv-unqualified scalar types, trivially copyable class types (Clause~\ref{class}), arrays of such types, and cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called \defn{trivially +types are collectively called \defn{trivially copyable types}. Scalar types, trivial class types (Clause~\ref{class}), arrays of such types and cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called +types are collectively called \defn{trivial types}. Scalar types, standard-layout class types (Clause~\ref{class}), arrays of such types and -cv-qualified versions of these types~(\ref{basic.type.qualifier}) +cv-qualified versions of these types are collectively called \defn{standard-layout types}. \pnum @@ -3634,7 +3670,7 @@ has all of the following properties: \begin{itemize} \item it has a trivial destructor, -\item it is either a closure type~(\ref{expr.prim.lambda}), +\item it is either a closure type~(\ref{expr.prim.lambda.closure}), an aggregate type~(\ref{dcl.init.aggr}), or has at least one constexpr constructor or constructor template (possibly inherited~(\ref{namespace.udecl}) from a base class) @@ -3645,6 +3681,14 @@ of non-volatile literal types. \end{itemize} \end{itemize} +\begin{note} +A literal type is one for which +it might be possible to create an object +within a constant expression. +It is not a guarantee that it is possible to create such an object, +nor is it a guarantee that any object of that type +will usable in a constant expression. +\end{note} \pnum \indextext{layout-compatible type}% @@ -3660,7 +3704,7 @@ \indextext{type!fundamental}% \indextext{type!integral}% \indextext{type!floating-point}% -\indextext{type!implementation-defined @\tcode{sizeof}}% +\indextext{type!implementation-defined \tcode{sizeof}}% \indextext{type!Boolean}% \indextext{type!\idxcode{char}}% \indextext{type!character}% @@ -3711,7 +3755,7 @@ \indextext{type!\idxcode{long}}% \indextext{type!\idxcode{long long}}% ``\tcode{signed char}'', ``\tcode{short int}'', ``\tcode{int}'', -``\tcode{long int}'', and ``\tcode{long} \tcode{long} \tcode{int}''. In +``\tcode{long int}'', and ``\tcode{long long int}''. In this list, each type provides at least as much storage as those preceding it in the list. \indextext{type!extended signed integer}% @@ -3721,7 +3765,7 @@ The standard and extended signed integer types are collectively called \defnx{signed integer types}{signed integer type}. -\indextext{integral type!implementation-defined @\tcode{sizeof}}% +\indextext{integral type!implementation-defined \tcode{sizeof}}% Plain \tcode{int}s have the natural size suggested by the architecture of the execution environment% @@ -3744,7 +3788,7 @@ \indextext{type!\idxcode{unsigned long long}}% ``\tcode{unsigned char}'', ``\tcode{unsigned short int}'', ``\tcode{unsigned int}'', ``\tcode{unsigned long int}'', and -``\tcode{unsigned} \tcode{long} \tcode{long} \tcode{int}'', each of +``\tcode{unsigned long long int}'', each of which occupies the same amount of storage and has the same alignment requirements~(\ref{basic.align}) as the corresponding signed integer type\footnote{See~\ref{dcl.type.simple} regarding the correspondence between types and @@ -3758,10 +3802,10 @@ \defn{extended unsigned integer type} with the same amount of storage and alignment requirements. The standard and extended unsigned integer types are collectively called \defnx{unsigned integer types}{unsigned integer type}. The range of non-negative -values of a signed integer type is a subrange of the corresponding -unsigned integer type, and the value -representation of each corresponding signed/unsigned type shall be the -same. +values of a signed integer type is +a subrange of the corresponding unsigned integer type, +the representation of the same value in each of the two types is the same, and +the value representation of each corresponding signed/unsigned type shall be the same. \indextext{type!standard integer}% \indextext{type!extended integer}% The standard signed integer types and standard unsigned integer types @@ -3848,13 +3892,13 @@ least as much precision as \tcode{double}. The set of values of the type \tcode{float} is a subset of the set of values of the type \tcode{double}; the set of values of the type \tcode{double} is a subset -of the set of values of the type \tcode{long} \tcode{double}. The value +of the set of values of the type \tcode{long double}. The value representation of floating-point types is \impldef{value representation of floating-point types}. \indextext{floating-point type!implementation-defined}% \begin{note} This International Standard imposes no requirements on the accuracy of -floating-point operations; see also~\ref{support.limits}. +floating-point operations; see also~\ref{support.limits}. \end{note} Integral and floating types are collectively called \defnx{arithmetic}{type!arithmetic} types. @@ -4061,9 +4105,9 @@ \defn{volatile-qualified} version, and a \defn{const-volatile-qualified} version. The type of an object~(\ref{intro.object}) includes the \grammarterm{cv-qualifier}{s} -specified in the \grammarterm{decl-specifier-seq}~(\ref{dcl.spec}), +specified in the \grammarterm{decl-specifier-seq}~(\ref{dcl.spec}), \grammarterm{declarator} (Clause~\ref{dcl.decl}), -\grammarterm{type-id}~(\ref{dcl.name}), or +\grammarterm{type-id}~(\ref{dcl.name}), or \grammarterm{new-type-id}~(\ref{expr.new}) when the object is created. \begin{itemize} \item A \defnx{const object}{object!const} is an object of type \tcode{const T} or a @@ -4090,8 +4134,8 @@ \indextext{array!\idxcode{const}}% A compound type~(\ref{basic.compound}) is not cv-qualified by the cv-qualifiers (if any) of the types from which it is compounded. Any -cv-qualifiers applied to an array type affect the array element type, -not the array type~(\ref{dcl.array}). +cv-qualifiers applied to an array type +affect the array element type~(\ref{dcl.array}). \pnum See~\ref{dcl.fct} and~\ref{class.this} regarding function @@ -4099,7 +4143,7 @@ \pnum There is a partial ordering on cv-qualifiers, so that a type can be -said to be \grammarterm{more cv-qualified} than another. +said to be \defn{more cv-qualified} than another. Table~\ref{tab:relations.on.const.and.volatile} shows the relations that constitute this ordering. @@ -4283,7 +4327,7 @@ \item a type that is a (possibly cv-qualified) base class type of the dynamic type of the object, -\item a \tcode{char} or \tcode{unsigned} \tcode{char} type. +\item a \tcode{char}, \tcode{unsigned char}, or \tcode{std::byte} type. \end{itemize} \rSec1[basic.align]{Alignment} @@ -4321,13 +4365,12 @@ \pnum \indextext{alignment!extended}% \indextext{alignment!new-extended}% -\indextext{over-aligned type}% -\indextext{type!over-aligned}% +\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~(\ref{dcl.align}). A type having an extended alignment -requirement is an \grammarterm{over-aligned type}. \begin{note} +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} diff --git a/source/classes.tex b/source/classes.tex index bd45a647f8..ab1b59fc24 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -81,7 +81,7 @@ \pnum If a class is marked with the \grammarterm{class-virt-specifier} \tcode{final} and it appears -as a \grammarterm{base-type-specifier} in a \grammarterm{base-clause} +as a \grammarterm{class-or-decltype} in a \grammarterm{base-clause} (Clause~\ref{class.derived}), the program is ill-formed. Whenever a \grammarterm{class-key} is followed by a \grammarterm{class-head-name}, the \grammarterm{identifier} \tcode{final}, and a colon or left brace, \tcode{final} is @@ -144,9 +144,8 @@ virtual functions or virtual base classes.\end{note} \indextext{class!standard-layout}% -\indextext{standard-layout class}% \pnum -A class \tcode{S} is a \grammarterm{standard-layout class} if it: +A class \tcode{S} is a \defn{standard-layout class} if it: \begin{itemize} \item has no non-static data members of type non-standard-layout class (or array of such types) or reference, @@ -213,14 +212,12 @@ \end{example} \indextext{struct!standard-layout}% -\indextext{standard-layout struct}% \indextext{union!standard-layout}% -\indextext{standard-layout union}% \pnum -A \grammarterm{standard-layout struct} is a standard-layout class +A \defn{standard-layout struct} is a standard-layout class defined with the \grammarterm{class-key} \tcode{struct} or the \grammarterm{class-key} \tcode{class}. -A \grammarterm{standard-layout union} is a standard-layout class +A \defn{standard-layout union} is a standard-layout class defined with the \grammarterm{class-key} \tcode{union}. @@ -250,7 +247,7 @@ struct T { // trivial but not standard-layout int i; -private: +private: int j; }; @@ -495,6 +492,9 @@ \indextext{definition!class}% The \grammarterm{member-specification} in a class definition declares the full set of members of the class; no member can be added elsewhere. +A \defn{direct member} of a class \tcode{X} is a member of \tcode{X} +that was first declared within the \grammarterm{member-specification} of \tcode{X}, +including anonymous union objects~(\ref{class.union.anon}) and direct members thereof. Members of a class are data members, member functions~(\ref{class.mfct}), nested types, enumerators, and member templates~(\ref{temp.mem}) and specializations thereof. @@ -806,7 +806,7 @@ \indextext{definition!member function}% A member function may be defined~(\ref{dcl.fct.def}) in its class definition, in which case it is an \term{inline} member -function~(\ref{dcl.fct.spec}), or it may be defined outside of its class +function~(\ref{dcl.inline}), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition. A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class @@ -832,7 +832,7 @@ 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. -See~\ref{basic.def.odr} and~\ref{dcl.fct.spec}. +See~\ref{basic.def.odr} and~\ref{dcl.inline}. \end{note} \pnum @@ -991,7 +991,7 @@ \pnum A non-static member function may be declared \tcode{const}, \tcode{volatile}, or \tcode{const} \tcode{volatile}. These -\grammarterm{cv-qualifiers} affect the type of the \tcode{this} +\grammarterm{cv-qualifier}{s} affect the type of the \tcode{this} pointer~(\ref{class.this}). They also affect the function type~(\ref{dcl.fct}) of the member function; a member function declared \tcode{const} is a \term{const} member function, a member function @@ -1231,7 +1231,7 @@ The static data member \tcode{run_chain} of class \tcode{process} is defined in global scope; the notation -\tcode{process\colcol{}run_chain} specifies that the member \tcode{run_chain} +\tcode{process::run_chain} specifies that the member \tcode{run_chain} is a member of class \tcode{process} and in the scope of class \tcode{process}. In the static data member definition, the \grammarterm{initializer} expression refers to the static data @@ -1325,7 +1325,7 @@ \pnum \indextext{bit-field!unnamed}% A declaration for a bit-field that omits the \grammarterm{identifier} -declares an \grammarterm{unnamed} bit-field. Unnamed bit-fields are not +declares an \defn{unnamed bit-field}. Unnamed bit-fields are not members and cannot be initialized. \begin{note} An unnamed bit-field is useful for padding to conform to @@ -1387,12 +1387,11 @@ \rSec2[class.nest]{Nested class declarations}% \indextext{definition!nested class}% -\indextext{class local|see{local class}}% -\indextext{class nested|see{nested class}} +\indextext{class!nested|see{nested class}} \pnum A class can be declared within another class. A class declared within -another is called a \grammarterm{nested} class. The name of a nested class +another is called a \defnx{nested}{nested class} class. The name of a nested class is local to its enclosing class. \indextext{nested class!scope of}% The nested class is in the scope of its enclosing class. @@ -1667,8 +1666,9 @@ \terminal{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} \end{ncbnftab} -is called an \defn{anonymous union}; it defines an unnamed object of unnamed -type. Each \grammarterm{member-declaration} in the \grammarterm{member-specification} +is called an \defn{anonymous union}; it defines an unnamed type and +an unnamed object of that type called an \defn{anonymous union object}. +Each \grammarterm{member-declaration} in the \grammarterm{member-specification} of an anonymous union shall either define a non-static data member or be a \grammarterm{static_assert-declaration}. \begin{note} @@ -1757,10 +1757,11 @@ \rSec1[class.local]{Local class declarations} \indextext{declaration!local class}% \indextext{definition!local class}% +\indextext{class!local|see{local class}}% \pnum A class can be declared within a function definition; such a class is -called a \grammarterm{local} class. The name of a local class is local to +called a \defnx{local}{local class} class. The name of a local class is local to its enclosing scope. \indextext{local class!scope of}% The local class is in the scope of the enclosing scope, and has the same diff --git a/source/compatibility.tex b/source/compatibility.tex index 0570090df6..72889bc128 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -146,7 +146,7 @@ names are referred to outside the \tcode{struct}. The latter is probably rare. -\ref{basic.link} [also \ref{dcl.type}] +\ref{basic.link} [also \ref{dcl.type}] \change A name of file scope that is explicitly declared \tcode{const}, and not explicitly declared \tcode{extern}, has internal linkage, while in C it would have external linkage. \rationale @@ -576,7 +576,7 @@ \rationale When comparing types in different translation units, \Cpp relies on name equivalence when C relies on structural equivalence. -Regarding parameter types: since the type defined in an parameter list +Regarding parameter types: since the type defined in a parameter list would be in the scope of the function, the only legal calls in \Cpp would be from within the function itself. \effect @@ -742,7 +742,7 @@ \rationale When classes become complicated, allowing such a redefinition after the type has been used can create confusion for \Cpp -programmers as to what the meaning of 'I' really is. +programmers as to what the meaning of \tcode{I} really is. \effect Deletion of semantically well-defined feature. \difficulty @@ -915,7 +915,7 @@ \ref{expr.log.and} \change \tcode{\&\&} is valid in a \grammarterm{type-name}. \rationale Required for new features. -\effect +\effect Valid \CppIII code may fail to compile or produce different results in this International Standard, as the following example illustrates: @@ -1114,7 +1114,6 @@ delete i; // single-object delete int* a = new int[3]; delete [] a; // array delete - return 0; } \end{codeblock} @@ -1323,7 +1322,6 @@ int main() { int flag = std::ios_base::hex; std::cout.setf(flag); // error: \tcode{setf} does not take argument of type \tcode{int} - return 0; } \end{codeblock} @@ -1577,7 +1575,7 @@ struct derived; struct base { friend struct derived; -private: +private: base(); }; struct derived : base {}; @@ -1677,6 +1675,21 @@ 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} +\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 +International Standard. +For example: + +\begin{codeblock} +#include +std::unique_ptr arr(new int[1]); +std::shared_ptr ptr(std::move(arr)); // error: \tcode{int(*)[]} is not compatible with \tcode{int*} +\end{codeblock} + \rSec2[diff.cpp14.string]{Clause \ref{strings}: strings library} \ref{basic.string} @@ -1711,7 +1724,7 @@ \begin{codeblock} #include -struct compare +struct compare { bool operator()(int a, int b) { @@ -1777,16 +1790,16 @@ nor are the C headers themselves part of \Cpp. \pnum -The headers \tcode{}\indextext{\idxhdr{ccomplex}} (\ref{ccomplex.syn}) -and \tcode{}\indextext{\idxhdr{ctgmath}} (\ref{ctgmath.syn}), as well +The \Cpp headers \tcode{}\indextext{\idxhdr{ccomplex}} (\ref{depr.ccomplex.syn}) +and \tcode{}\indextext{\idxhdr{ctgmath}} (\ref{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 content from the C standard library and instead merely include other headers from the \Cpp standard library. \pnum -The headers \tcode{}, \tcode{}~(\ref{cstdalign.syn}), -and \tcode{}~(\ref{cstdbool.syn}) are meaningless in \Cpp. Use of +The headers \tcode{}, \tcode{}~(\ref{depr.cstdalign.syn}), +and \tcode{}~(\ref{depr.cstdbool.syn}) are meaningless in \Cpp. Use of the \Cpp headers \tcode{}, \tcode{}, \tcode{}, and \tcode{} is deprecated~(\ref{depr.c.headers}). @@ -1851,7 +1864,7 @@ \pnum The token \tcode{alignas} is a keyword in this International Standard (\ref{lex.key}). It does not appear as a macro name defined -in \tcode{}\indexlibrary{\idxhdr{cstdalign}}~(\ref{cstdalign.syn}). +in \tcode{}\indexlibrary{\idxhdr{cstdalign}}~(\ref{depr.cstdalign.syn}). \rSec3[diff.header.stdbool.h]{Header \tcode{}} \indexlibrary{\idxhdr{stdbool.h}}% @@ -1860,7 +1873,7 @@ The tokens \tcode{bool}, \tcode{true}, and \tcode{false} are keywords in this International Standard (\ref{lex.key}). They do not appear as macro names defined in -\tcode{}\indexlibrary{\idxhdr{cstdbool}}~(\ref{cstdbool.syn}). +\tcode{}\indexlibrary{\idxhdr{cstdbool}}~(\ref{depr.cstdbool.syn}). \rSec3[diff.null]{Macro \tcode{NULL}} diff --git a/source/config.tex b/source/config.tex index c3e390cbc7..83ae410977 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,9 +1,9 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4640} -\newcommand{\prevdocno}{N4618} -\newcommand{\cppver}{201402L} +\newcommand{\docno}{N4659} +\newcommand{\prevdocno}{N4640} +\newcommand{\cppver}{201703L} %% Release date \newcommand{\reldate}{\today} diff --git a/source/containers.tex b/source/containers.tex index ac57a3f52b..9b793e43c7 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -202,24 +202,21 @@ \tcode{a.cbegin()} & \tcode{const_iterator} & - \tcode{const_cast(a).begin();} & + \tcode{const_cast<\brk{}X const\&\brk{}>(a)\brk{}.begin();} & & constant \\ \rowsep \tcode{a.cend()} & \tcode{const_iterator} & - \tcode{const_cast(a).end();} & + \tcode{const_cast<\brk{}X const\&\brk{}>(a)\brk{}.end();} & & constant \\ \rowsep \tcode{a == b} & convertible to \tcode{bool} & \tcode{==} is an equivalence relation. - - \tcode{equal(a.begin(),} - \tcode{a.end(), b.begin(),} - \tcode{b.end())} & - \requires\ \tcode{T} is \tcode{EqualityComparable} & + \tcode{equal(\brk{}a.begin(), a.end(), b.begin(), b.end())} & + \requires\ \tcode{T} is \tcode{EqualityCompar\-a\-ble} & Constant if \tcode{a.size() != b.size()}, linear otherwise \\ \rowsep @@ -249,23 +246,20 @@ \tcode{a.size()} & \tcode{size_type} & - \tcode{distance(a.begin(),} - \tcode{a.end())} & + \tcode{distance(\brk{}a.begin(), a.end())} & & constant \\ \rowsep \tcode{a.max_size()} & \tcode{size_type} & - \tcode{distance(begin(),} - \tcode{end())} + \tcode{distance(\brk{}begin(), end())} for the largest possible container & & constant \\ \rowsep \tcode{a.empty()} & convertible to \tcode{bool} & - \tcode{a.begin() ==} - \tcode{a.end()} & + \tcode{a.begin() == a.end()} & & constant \\ @@ -277,7 +271,7 @@ \begin{note} The algorithm \tcode{equal()} is defined in Clause~\ref{algorithms}. \end{note} - + \pnum The member function \tcode{size()} returns the number of elements in the container. The number of elements is defined by the rules of @@ -547,7 +541,7 @@ \end{codeblock} where \tcode{p} is the address of the uninitialized storage for the element allocated within \tcode{X}. - + \item \tcode{T} is \defnx{\tcode{MoveInsertable} into \tcode{X}} {MoveInsertable into X@\tcode{MoveInsertable} into \tcode{X}} @@ -706,6 +700,24 @@ \end{libreqtab4a} +\pnum +The behavior of certain container member functions and deduction guides +depends on whether types qualify as input iterators or allocators. +The extent to which an implementation determines that a type cannot be an input +iterator is unspecified, except that as a minimum integral types shall not qualify +as input iterators. +Likewise, the extent to which an implementation determines that a type cannot be +an allocator is unspecified, except that as a minimum a type \tcode{A} shall not qualify +as an allocator unless it satisfies both of the following conditions: + +\begin{itemize} +\item The \grammarterm{qualified-id} \tcode{A::value_type} +is valid and denotes a type~(\ref{temp.deduct}). + +\item The expression \tcode{declval().allocate(size_t\{\})} +is well-formed when treated as an unevaluated operand. +\end{itemize} + \rSec2[container.requirements.dataraces]{Container data races} \pnum @@ -838,10 +850,10 @@ \tcode{a.emplace(p, args)} & \tcode{iterator} & \requires\ \tcode{T} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector} and \tcode{deque}, - T is also + \tcode{T} is also \tcode{MoveInsertable} into \tcode{X} and \tcode{MoveAssignable}. \effects\ Inserts an object of type \tcode{T} constructed with - \tcode{std::forward(args)...} before \tcode{p}. \\ \rowsep + \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,t)} & \tcode{iterator} & @@ -1006,12 +1018,13 @@ are called with a type \tcode{InputIterator} that does not qualify as an input iterator, then these functions shall not participate in overload resolution. -\end{itemize} -\pnum -The extent to which an implementation determines that a type cannot be an input -iterator is unspecified, except that as a minimum integral types shall not qualify -as input iterators. +\item A deduction guide for a sequence container shall not participate in overload resolution +if it has an \tcode{InputIterator} template parameter and a type that does not +qualify as an input iterator is deduced for that parameter, +or if it has an \tcode{Allocator} template parameter and a type that does not +qualify as an allocator is deduced for that parameter. +\end{itemize} \pnum Table~\ref{tab:containers.sequence.optional} lists operations @@ -1056,9 +1069,9 @@ \tcode{vector} \\ \rowsep -\tcode{a.emplace_-} \tcode{front(args)} & +\tcode{a.emplace_\-front(args)} & \tcode{reference} & - Prepends an object of type \tcode{T} constructed with \tcode{std::forward(args)...}.\br + Prepends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \returns{} \tcode{a.front()}. & \tcode{deque}, @@ -1066,9 +1079,9 @@ \tcode{list} \\ \rowsep -\tcode{a.emplace_-} \tcode{back(args)} & +\tcode{a.emplace_\-back(args)} & \tcode{reference} & - Appends an object of type \tcode{T} constructed with \tcode{std::forward(args)...}.\br + Appends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} shall also be \tcode{MoveInsertable} into \tcode{X}.\br @@ -1213,7 +1226,7 @@ is empty, it contains no allocator. \pnum -Class \tcode{\textit{node_handle}} is for exposition only. An implementation is +Class \tcode{\placeholder{node_handle}} is for exposition only. An implementation is permitted to provide equivalent functionality without providing a class with this name. @@ -1226,7 +1239,7 @@ \begin{codeblock} template<@\unspecnc@> - class @\textit{node_handle}@ { + class @\placeholder{node_handle}@ { public: // These type declarations are described in Tables \ref{tab:containers.associative.requirements} and \ref{tab:HashRequirements}. using value_type = @\seebelownc{}@; // not present for map containers @@ -1242,10 +1255,10 @@ optional alloc_; public: - constexpr @\textit{node_handle}@() noexcept : ptr_(), alloc_() {} - ~@\textit{node_handle}@(); - @\textit{node_handle}@(@\textit{node_handle}@&&) noexcept; - @\textit{node_handle}@& operator=(@\textit{node_handle}@&&); + constexpr @\placeholdernc{node_handle}@() noexcept : ptr_(), alloc_() {} + ~@\placeholdernc{node_handle}@(); + @\placeholdernc{node_handle}@(@\placeholdernc{node_handle}@&&) noexcept; + @\placeholdernc{node_handle}@& operator=(@\placeholdernc{node_handle}@&&); value_type& value() const; // not present for map containers key_type& key() const; // not present for set containers @@ -1255,32 +1268,32 @@ explicit operator bool() const noexcept; bool empty() const noexcept; - void swap(@\textit{node_handle}@&) + void swap(@\placeholdernc{node_handle}@&) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); - friend void swap(@\textit{node_handle}@& x, @\textit{node_handle}@& y) noexcept(noexcept(x.swap(y))) { + friend void swap(@\placeholdernc{node_handle}@& x, @\placeholdernc{node_handle}@& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } }; \end{codeblock} -\rSec3[container.node.cons]{\tcode{\textit{node_handle}} constructors, copy, and assignment} +\rSec3[container.node.cons]{\tcode{\placeholder{node_handle}} constructors, copy, and assignment} \begin{itemdecl} -@\textit{node_handle}@(@\textit{node_handle}@&& nh) noexcept; +@\placeholdernc{node_handle}@(@\placeholdernc{node_handle}@&& nh) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{\textit{node_handle}} object initializing +\effects Constructs a \tcode{\placeholder{node_handle}} object initializing \tcode{ptr_} with \tcode{nh.ptr_}. Move constructs \tcode{alloc_} with \tcode{nh.alloc_}. Assigns \tcode{nullptr} to \tcode{nh.ptr_} and assigns \tcode{nullopt} to \tcode{nh.alloc_}. \end{itemdescr} \begin{itemdecl} -@\textit{node_handle}@& operator=(@\textit{node_handle}@&& nh); +@\placeholdernc{node_handle}@& operator=(@\placeholdernc{node_handle}@&& nh); \end{itemdecl} \begin{itemdescr} @@ -1290,25 +1303,33 @@ is \tcode{true}, or \tcode{alloc_ == nh.alloc_}. \pnum -\effects If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} +\effects +\begin{itemize} +\item +If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} subobject in the \tcode{container_node_type} object pointed to by \tcode{ptr_} by calling \tcode{ator_traits::destroy}, then deallocates \tcode{ptr_} by calling \tcode{ator_traits::rebind_traits::deallocate}. +\item Assigns \tcode{nh.ptr_} to \tcode{ptr_}. +\item If \tcode{!alloc\textunderscore} or \tcode{ator_traits::propagate_on_container_move_assignment} -is \tcode{true}, move assigns \tcode{nh.alloc_} to \tcode{alloc_}. Assigns +is \tcode{true}, move assigns \tcode{nh.alloc_} to \tcode{alloc_}. +\item +Assigns \tcode{nullptr} to \tcode{nh.ptr_} and assigns \tcode{nullopt} to \tcode{nh.alloc_}. +\end{itemize} \pnum \returns \tcode{*this}. \pnum \throws Nothing. \end{itemdescr} -\rSec3[container.node.dtor]{\tcode{\textit{node_handle}} destructor} +\rSec3[container.node.dtor]{\tcode{\placeholder{node_handle}} destructor} \begin{itemdecl} -~@\textit{node_handle}@(); +~@\placeholdernc{node_handle}@(); \end{itemdecl} \begin{itemdescr} @@ -1319,7 +1340,7 @@ \tcode{ator_traits::rebind_traits::deallocate}. \end{itemdescr} -\rSec3[container.node.observers]{\tcode{\textit{node_handle}} observers} +\rSec3[container.node.observers]{\tcode{\placeholder{node_handle}} observers} \begin{itemdecl} value_type& value() const; @@ -1408,10 +1429,10 @@ \returns \tcode{ptr_ == nullptr}. \end{itemdescr} -\rSec3[container.node.modifiers]{\tcode{\textit{node_handle}} modifiers} +\rSec3[container.node.modifiers]{\tcode{\placeholder{node_handle}} modifiers} \begin{itemdecl} -void swap(@\textit{node_handle}@& nh) +void swap(@\placeholdernc{node_handle}@& nh) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); \end{itemdecl} @@ -1437,7 +1458,7 @@ \begin{codeblock} template -struct @\textit{INSERT_RETURN_TYPE}@ +struct @\placeholder{INSERT_RETURN_TYPE}@ { Iterator position; bool inserted; @@ -1446,8 +1467,8 @@ \end{codeblock} \pnum -The name \textit{\tcode{INSERT_RETURN_TYPE}} is exposition only. -\textit{\tcode{INSERT_RETURN_TYPE}} has the template parameters, +The name \tcode{\placeholder{INSERT_RETURN_TYPE}} is exposition only. +\tcode{\placeholder{INSERT_RETURN_TYPE}} has the template parameters, data members, and special members specified above. It has no base classes or members other than those specified. @@ -1631,7 +1652,7 @@ compile time \\ \rowsep \tcode{X::node_type} & - a specialization of a \tcode{\textit{node_handle}} + a specialization of a \tcode{\placeholder{node_handle}} class template, such that the public nested types are the same types as the corresponding types in \tcode{X}. & see~\ref{container.node} & @@ -1698,11 +1719,11 @@ returns an object of \tcode{value_compare} constructed out of the comparison object & constant \\ \rowsep -\tcode{a_uniq.} \tcode{emplace(args)} & - \tcode{pair} & +\tcode{a_uniq.\brk{}emplace(\brk{}args)} & + \tcode{pair<\brk{}iterator, bool>} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} if and only if there is no + \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} component of the returned pair is \tcode{true} if and only if the insertion takes place, and the iterator @@ -1710,19 +1731,19 @@ key of \tcode{t}. & logarithmic \\ \rowsep -\tcode{a_eq.} \tcode{emplace(args)} & +\tcode{a_eq.\brk{}emplace(\brk{}args)} & \tcode{iterator} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} and returns the iterator pointing + \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. If a range containing elements equivalent to \tcode{t} exists in \tcode{a_eq}, \tcode{t} is inserted at the end of that range. & logarithmic \\ \rowsep -\tcode{a.emplace_hint(p, args)} & +\tcode{a.emplace_\-hint(\brk{}p, args)} & \tcode{iterator} & - equivalent to \tcode{a.emplace(} \tcode{std::forward(args)...)}. + equivalent to \tcode{a.emplace(} \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...)}. Return value is an iterator pointing to the element with the key equivalent to the newly inserted element. The element is inserted as close as possible to the position just prior @@ -1730,8 +1751,8 @@ logarithmic in general, but amortized constant if the element is inserted right before \tcode{p} \\ \rowsep -\tcode{a_uniq.} \tcode{insert(t)} & - \tcode{pair} & +\tcode{a_uniq.\brk{}insert(\brk{}t)} & + \tcode{pair<\brk{}iterator, bool>} & \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 @@ -1743,7 +1764,7 @@ equivalent to the key of \tcode{t}. & logarithmic \\ \rowsep -\tcode{a_eq.insert(t)} & +\tcode{a_eq.\brk{}insert(\brk{}t)} & \tcode{iterator} & \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be @@ -1755,8 +1776,7 @@ is inserted at the end of that range. & logarithmic \\ \rowsep -\tcode{a.insert(}\br - \tcode{p, t)} & +\tcode{a.\brk{}insert(\brk{}p, t)} & \tcode{iterator} & \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be @@ -1770,23 +1790,21 @@ logarithmic in general, but amortized constant if \tcode{t} is inserted right before \tcode{p}. \\ \rowsep -\tcode{a.insert(}\br - \tcode{i, j)} & +\tcode{a.\brk{}insert(\brk{}i, j)} & \tcode{void} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \requires \tcode{i}, \tcode{j} are not iterators into \tcode{a}. inserts each element from the range \range{i}{j} if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys. & - $N\log (\tcode{a.size()} + N)$, where $N$ has the value \tcode{distance(i, j)} \\ \rowsep + $N \log (\tcode{a.size()} + N)$, where $N$ has the value \tcode{distance(i, j)} \\ \rowsep -\tcode{a.insert(il)} & +\tcode{a.\brk{}insert(\brk{}il)} & \tcode{void} & equivalent to \tcode{a.insert(il.begin(), il.end())} & \\ \rowsep -\tcode{a_uniq.}\br - \tcode{insert(nh)} & +\tcode{a_uniq.\brk{}insert(\brk{}nh)} & \tcode{insert_return_type} & \requires \tcode{nh} is empty or \tcode{a_uniq.get_allocator() == nh.get_allocator()}.\br @@ -1802,8 +1820,7 @@ points to an element with a key equivalent to \tcode{nh.key()}. & logarithmic \\ \rowsep -\tcode{a_eq.}\br - \tcode{insert(nh)} & +\tcode{a_eq.\brk{}insert(\brk{}nh)} & \tcode{iterator} & \requires \tcode{nh} is empty or \tcode{a_eq.get_allocator() == nh.get_allocator()}.\br @@ -1815,7 +1832,7 @@ \postconditions \tcode{nh} is empty. & logarithmic \\ \rowsep -\tcode{a.insert(p, nh)} & +\tcode{a.\brk{}insert(\brk{}p, nh)} & \tcode{iterator} & \requires \tcode{nh} is empty or \tcode{a.get_allocator() == nh.get_allocator()}.\br @@ -1830,14 +1847,14 @@ logarithmic in general, but amortized constant if the element is inserted right before \tcode{p}. \\ \rowsep -\tcode{a.extract(k)} & +\tcode{a.\brk{}extract(\brk{}k)} & \tcode{node_type} & removes the first element in the container with key equivalent to \tcode{k}. Returns a \tcode{node_type} owning the element if found, otherwise an empty \tcode{node_type}. & $\log (\tcode{a.size()})$ \\ \rowsep -\tcode{a.extract(q)} & +\tcode{a.\brk{}extract(\brk{}q)} & \tcode{node_type} & removes the element pointed to by \tcode{q}. Returns a \tcode{node_type} owning that element. & @@ -1948,15 +1965,15 @@ logarithmic \\ \rowsep \tcode{b.equal_range(k)} & - \tcode{pair}; - \tcode{pair} for constant \tcode{b}. & + \tcode{pair<\brk{}iterator, iterator>}; + \tcode{pair<\brk{}const_iterator, const_iterator>} for constant \tcode{b}. & equivalent to \tcode{make_pair(b.lower_bound(k), b.upper_bound(k))}. & logarithmic \\ \rowsep \tcode{a_tran.}\br \tcode{equal_range(ke)} & - \tcode{pair}; - \tcode{pair} for constant \tcode{a_tran}. & + \tcode{pair<\brk{}iterator, iterator>}; + \tcode{pair<\brk{}const_iterator, const_iterator>} for constant \tcode{a_tran}. & equivalent to \tcode{make_pair(}\br \tcode{a_tran.lower_bound(ke), a_tran.upper_bound(ke))}. & logarithmic \\ @@ -2018,6 +2035,20 @@ resolution unless the \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid and denotes a type~(\ref{temp.deduct}). +\pnum +A deduction guide for an associative container shall not participate in overload resolution +if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter +and a type that does not qualify as an input iterator is deduced for that parameter. + +\item It has an \tcode{Allocator} template parameter +and a type that does not qualify as an allocator is deduced for that parameter. + +\item It has a \tcode{Compare} template parameter +and a type that qualifies as an allocator is deduced for that parameter. +\end{itemize} + \indextext{associative containers!exception safety}% \indextext{associative containers!requirements}% \rSec3[associative.reqmts.except]{Exception safety guarantees} @@ -2260,7 +2291,7 @@ \\ \rowsep % \tcode{X::node_type} & - a specialization of a \tcode{\textit{node_handle}} + a specialization of a \tcode{\placeholder{node_handle}} class template, such that the public nested types are the same types as the corresponding types in \tcode{X}. & see~\ref{container.node} & @@ -2417,7 +2448,7 @@ \tcode{pair} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} if and only if there is no + \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} component of the returned pair is \tcode{true} if and only if the insertion takes place, and the iterator @@ -2430,7 +2461,7 @@ \tcode{iterator} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} and returns the iterator pointing + \tcode{std::forward<\brk{}Args>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. & Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.}\br\tcode{size()}}. \\ \rowsep @@ -2438,7 +2469,7 @@ \tcode{a.emplace_hint(p, args)} & \tcode{iterator} & \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Equivalent to \tcode{a.emplace(} \tcode{std::forward(args)...)}. + \effects\ Equivalent to \tcode{a.emplace(} \tcode{std::forward<\brk{}Args>(\brk{}args)...)}. Return value is an iterator pointing to the element with the key equivalent to the newly inserted element. The \tcode{const_iterator} \tcode{p} is a hint pointing to where the search should start. Implementations are @@ -2480,7 +2511,7 @@ \tcode{CopyInsertable} into \tcode{X}.\br \effects\ Equivalent to a.insert(t). Return value is an iterator pointing to the element with the key equivalent to that of \tcode{t}. The -iterator \tcode{q} is a hint pointing to where the search should +iterator \tcode{p} is a hint pointing to where the search should start. Implementations are permitted to ignore the hint.% \indextext{unordered associative containers!\idxcode{insert}}% \indextext{\idxcode{insert}!unordered associative containers}% @@ -2494,8 +2525,8 @@ Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% \indextext{unordered associative containers!\idxcode{insert}}% \indextext{\idxcode{insert}!unordered associative containers}% -& Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. Worst - case $\bigoh{N(\tcode{a.size()} + 1)}$. +& Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. + Worst case \bigoh{N(\tcode{a.size()}\brk{}+\brk{}1)}. \\ \rowsep % \tcode{a.insert(il)} @@ -2519,7 +2550,7 @@ if the insertion failed, \tcode{inserted} is \tcode{false}, \tcode{node} has the previous value of \tcode{nh}, and \tcode{position} points to an element with a key equivalent to \tcode{nh.key()}. & - Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.}\br\tcode{size()}}. \\ \rowsep + Average case \bigoh{1}, worst case \bigoh{\brk{}\tcode{a_uniq.}\brk{}\tcode{size()}}. \\ \rowsep % \tcode{a_eq.}\br \tcode{insert(nh)} & @@ -2530,7 +2561,7 @@ Otherwise, inserts the element owned by \tcode{nh} and returns an iterator pointing to the newly inserted element.\br \postconditions \tcode{nh} is empty. & - Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.size()}}. \\ \rowsep + Average case \bigoh{1}, worst case \bigoh{\brk{}\tcode{a_eq.}\brk{}\tcode{size()}}. \\ \rowsep % \tcode{a.insert(q, nh)} & \tcode{iterator} & @@ -2837,6 +2868,23 @@ obtained while it is owned by a \tcode{node_type} are invalidated if the element is successfully inserted. +\pnum +A deduction guide for an unordered associative container shall not participate in overload resolution +if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter +and a type that does not qualify as an input iterator is deduced for that parameter. + +\item It has an \tcode{Allocator} template parameter +and a type that does not qualify as an allocator is deduced for that parameter. + +\item It has a \tcode{Hash} template parameter +and an integral type or a type that qualifies as an allocator is deduced for that parameter. + +\item It has a \tcode{Pred} template parameter +and a type that qualifies as an allocator is deduced for that parameter. +\end{itemize} + \rSec3[unord.req.except]{Exception safety guarantees} \pnum @@ -2882,7 +2930,7 @@ #include namespace std { - // \ref{array}, class template array + // \ref{array}, class template \tcode{array} template struct array; template bool operator==(const array& x, const array& y); @@ -2925,7 +2973,7 @@ #include namespace std { - // \ref{deque}, class template deque + // \ref{deque}, class template \tcode{deque} template > class deque; template bool operator==(const deque& x, const deque& y); @@ -2959,7 +3007,7 @@ #include namespace std { - // \ref{forwardlist}, class template forward_list + // \ref{forwardlist}, class template \tcode{forward_list} template > class forward_list; template bool operator==(const forward_list& x, const forward_list& y); @@ -2993,7 +3041,7 @@ #include namespace std { - // \ref{list}, class template list + // \ref{list}, class template \tcode{list} template > class list; template bool operator==(const list& x, const list& y); @@ -3027,7 +3075,7 @@ #include namespace std { - // \ref{vector}, class template vector + // \ref{vector}, class template \tcode{vector} template > class vector; template bool operator==(const vector& x, const vector& y); @@ -3045,7 +3093,7 @@ void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); - // \ref{vector.bool}, class vector + // \ref{vector.bool}, class \tcode{vector} template class vector; // hash support @@ -3152,6 +3200,9 @@ constexpr T * data() noexcept; constexpr const T * data() const noexcept; }; + + template + array(T, U...) -> array; } \end{codeblock} @@ -3169,6 +3220,15 @@ require that \tcode{T} be \tcode{MoveConstructible} or \tcode{MoveAssignable}, respectively. +\begin{itemdecl} +template + array(T, U...) -> array; +\end{itemdecl} +\begin{itemdescr} +\pnum +\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}% @@ -3432,6 +3492,11 @@ void clear() noexcept; }; + template::value_type>> + deque(InputIterator, InputIterator, Allocator = Allocator()) + -> deque::value_type, Allocator>; + template bool operator==(const deque& x, const deque& y); template @@ -3583,7 +3648,7 @@ \pnum \remarks \tcode{shrink_to_fit} invalidates all the references, pointers, and iterators -referring to the elements in the sequence. +referring to the elements in the sequence as well as the past-the-end iterator. \end{itemdescr} \rSec3[deque.modifiers]{\tcode{deque} modifiers} @@ -3805,7 +3870,7 @@ void resize(size_type sz, const value_type& c); void clear() noexcept; - // \ref{forwardlist.ops}, forward_list operations + // \ref{forwardlist.ops}, \tcode{forward_list} operations void splice_after(const_iterator position, forward_list& x); void splice_after(const_iterator position, forward_list&& x); void splice_after(const_iterator position, forward_list& x, @@ -3834,6 +3899,11 @@ void reverse() noexcept; }; + template::value_type>> + forward_list(InputIterator, InputIterator, Allocator = Allocator()) + -> forward_list::value_type, Allocator>; + template bool operator==(const forward_list& x, const forward_list& y); template @@ -3857,7 +3927,7 @@ \pnum An incomplete type \tcode{T} may be used when instantiating \tcode{forward_list} if the allocator satisfies the -allocator completeness requirements~\ref{allocator.requirements.completeness}. +allocator completeness requirements~(\ref{allocator.requirements.completeness}). \tcode{T} shall be complete before any member of the resulting specialization of \tcode{forward_list} is referenced. @@ -4155,7 +4225,7 @@ \begin{itemdescr} \pnum \effects If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), -end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} +end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} copies of \tcode{c} at the end of the list. \pnum @@ -4548,6 +4618,11 @@ void reverse() noexcept; }; + template::value_type>> + list(InputIterator, InputIterator, Allocator = Allocator()) + -> list::value_type, Allocator>; + template bool operator==(const list& x, const list& y); template @@ -4571,7 +4646,7 @@ \pnum An incomplete type \tcode{T} may be used when instantiating \tcode{list} if the allocator satisfies the -allocator completeness requirements~\ref{allocator.requirements.completeness}. +allocator completeness requirements~(\ref{allocator.requirements.completeness}). \tcode{T} shall be complete before any member of the resulting specialization of \tcode{list} is referenced. @@ -5059,6 +5134,8 @@ \pnum \effects Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. +If an exception is thrown, +the order of the elements in \tcode{*this} is unspecified. Does not affect the validity of iterators and references. \pnum @@ -5067,7 +5144,7 @@ \pnum \complexity Approximately -$N \log(N)$ +$N \log N$ comparisons, where \tcode{N == size()}. \end{itemdescr} @@ -5218,6 +5295,11 @@ void clear() noexcept; }; + template::value_type>> + vector(InputIterator, InputIterator, Allocator = Allocator()) + -> vector::value_type, Allocator>; + template bool operator==(const vector& x, const vector& y); template @@ -5243,7 +5325,7 @@ \pnum An incomplete type \tcode{T} may be used when instantiating \tcode{vector} if the allocator satisfies the -allocator completeness requirements~\ref{allocator.requirements.completeness}. +allocator completeness requirements~(\ref{allocator.requirements.completeness}). \tcode{T} shall be complete before any member of the resulting specialization of \tcode{vector} is referenced. @@ -5328,7 +5410,7 @@ calls to the copy constructor of \tcode{T} and order -$\log(N)$ +$\log N$ reallocations if they are just input iterators. \end{itemdescr} @@ -5412,7 +5494,7 @@ \begin{note} The request is non-binding to allow latitude for implementation-specific optimizations. \end{note} It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} -by causing reallocation. +by causing reallocation. If an exception is thrown other than by the move constructor of a non-\tcode{CopyInsertable} \tcode{T} there are no effects. @@ -5421,7 +5503,7 @@ \pnum \remarks Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence. +referring to the elements in the sequence as well as the past-the-end iterator. If no reallocation happens, they remain valid. \end{itemdescr} @@ -5567,8 +5649,7 @@ \pnum \throws Nothing unless an exception is thrown by the -copy constructor, move constructor, -assignment operator, or move assignment operator of +assignment operator or move assignment operator of \tcode{T}. \end{itemdescr} @@ -5639,7 +5720,7 @@ vector(const vector&, const Allocator&); vector(vector&&, const Allocator&); vector(initializer_list, const Allocator& = Allocator())); - ~vector(); + ~vector(); vector& operator=(const vector& x); vector& operator=(vector&& x); vector& operator=(initializer_list); @@ -5771,6 +5852,22 @@ \tcode{multimap}; the header \tcode{} defines the class templates \tcode{set} and \tcode{multiset}. +\pnum +The following exposition-only alias templates may appear in deduction guides for associative containers: + +\begin{codeblock} +template + using iter_key_t = remove_const_t< + typename iterator_traits::value_type::first_type>; // \expos +template + using iter_val_t + = typename iterator_traits::value_type::second_type; // \expos +template + using iter_to_alloc_t + = pair::value_type::first_type>, + typename iterator_traits::value_type::second_type>; // \expos +\end{codeblock} + \rSec2[associative.map.syn]{Header \tcode{} synopsis} \indextext{\idxhdr{map}}% @@ -5779,8 +5876,8 @@ #include namespace std { - // \ref{map}, class template map - template , + // \ref{map}, class template \tcode{map} + template , class Allocator = allocator>> class map; template @@ -5806,8 +5903,8 @@ map& y) noexcept(noexcept(x.swap(y))); - // \ref{multimap}, class template multimap - template , + // \ref{multimap}, class template \tcode{multimap} + template , class Allocator = allocator>> class multimap; template @@ -5834,11 +5931,11 @@ noexcept(noexcept(x.swap(y))); namespace pmr { - template > + template > using map = std::map>>; - template > + template > using multimap = std::multimap>>; } @@ -5854,8 +5951,8 @@ #include namespace std { - // \ref{set}, class template set - template , + // \ref{set}, class template \tcode{set} + template , class Allocator = allocator> class set; template @@ -5881,8 +5978,8 @@ set& y) noexcept(noexcept(x.swap(y))); - // \ref{multiset}, class template multiset - template , + // \ref{multiset}, class template \tcode{multiset} + template , class Allocator = allocator> class multiset; template @@ -5909,11 +6006,11 @@ noexcept(noexcept(x.swap(y))); namespace pmr { - template > + template > using set = std::set>; - template > + template > using multiset = std::multiset>; } @@ -5965,7 +6062,7 @@ \begin{codeblock} namespace std { - template , + template , class Allocator = allocator>> class map { public: @@ -5986,7 +6083,7 @@ using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using node_type = @\unspec@; - using insert_return_type = @\textit{INSERT_RETURN_TYPE}@; + using insert_return_type = @\placeholdernc{INSERT_RETURN_TYPE}@; class value_compare { friend class map; @@ -6138,6 +6235,24 @@ pair equal_range(const K& x) const; }; + template>, + class Allocator = allocator>> + map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) + -> map, iter_val_t, Compare, Allocator>; + + template, + class Allocator = allocator>> + map(initializer_list>, Compare = Compare(), Allocator = Allocator()) + -> map; + + template + map(InputIterator, InputIterator, Allocator) + -> map, iter_val_t, + less>, Allocator>; + + template + map(initializer_list>, Allocator) -> map, Allocator>; + template bool operator==(const map& x, const map& y); @@ -6208,7 +6323,7 @@ Linear in $N$ if the range \range{first}{last} is already sorted using \tcode{comp} -and otherwise $N \log{N}$, where $N$ +and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -6269,7 +6384,7 @@ \begin{itemdescr} \pnum \effects -The first form is equivalent to +The first form is equivalent to \tcode{return emplace(std::forward

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

(x))}. @@ -6498,7 +6613,7 @@ \begin{codeblock} namespace std { - template , + template , class Allocator = allocator>> class multimap { public: @@ -6647,6 +6762,25 @@ pair equal_range(const K& x) const; }; + template>, + class Allocator = allocator>> + multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) + -> multimap, iter_val_t, Compare, Allocator>; + + template, + class Allocator = allocator>> + multimap(initializer_list>, Compare = Compare(), Allocator = Allocator()) + -> multimap; + + template + multimap(InputIterator, InputIterator, Allocator) + -> multimap, iter_val_t, + less>, Allocator>; + + template + multimap(initializer_list>, Allocator) + -> multimap, Allocator>; + template bool operator==(const multimap& x, const multimap& y); @@ -6717,7 +6851,7 @@ Linear in $N$ if the range \range{first}{last} is already sorted using \tcode{comp} -and otherwise $N \log{N}$, +and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -6733,7 +6867,7 @@ \begin{itemdescr} \pnum \effects -The first form is equivalent to +The first form is equivalent to \tcode{return emplace(std::forward

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

(x))}. @@ -6806,7 +6940,7 @@ \begin{codeblock} namespace std { - template , + template , class Allocator = allocator> class set { public: @@ -6827,7 +6961,7 @@ using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using node_type = @\unspec@; - using insert_return_type = @\textit{INSERT_RETURN_TYPE}@; + using insert_return_type = @\placeholdernc{INSERT_RETURN_TYPE}@; // \ref{set.cons}, construct/copy/destroy set() : set(Compare()) { } @@ -6941,6 +7075,25 @@ pair equal_range(const K& x) const; }; + template::value_type>, + class Allocator = allocator::value_type>> + set(InputIterator, InputIterator, + Compare = Compare(), Allocator = Allocator()) + -> set::value_type, Compare, Allocator>; + + template, class Allocator = allocator> + set(initializer_list, Compare = Compare(), Allocator = Allocator()) + -> set; + + template + set(InputIterator, InputIterator, Allocator) + -> set::value_type, + less::value_type>, Allocator>; + + template + set(initializer_list, Allocator) -> set, Allocator>; + template bool operator==(const set& x, const set& y); @@ -7008,7 +7161,7 @@ Linear in $N$ if the range \range{first}{last} is already sorted using \tcode{comp} -and otherwise $N \log{N}$, +and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -7074,7 +7227,7 @@ \begin{codeblock} namespace std { - template , + template , class Allocator = allocator> class multiset { public: @@ -7208,6 +7361,25 @@ pair equal_range(const K& x) const; }; + template::value_type>, + class Allocator = allocator::value_type>> + multiset(InputIterator, InputIterator, + Compare = Compare(), Allocator = Allocator()) + -> multiset::value_type, Compare, Allocator>; + + template, class Allocator = allocator> + multiset(initializer_list, Compare = Compare(), Allocator = Allocator()) + -> multiset; + + template + multiset(InputIterator, InputIterator, Allocator) + -> multiset::value_type, + less::value_type>, Allocator>; + + template + multiset(initializer_list, Allocator) -> multiset, Allocator>; + template bool operator==(const multiset& x, const multiset& y); @@ -7275,7 +7447,7 @@ Linear in $N$ if the range \range{first}{last} -is already sorted using \tcode{comp} and otherwise $N \log{N}$, +is already sorted using \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -7306,6 +7478,10 @@ \tcode{unordered_multimap}; the header \tcode{} defines the class templates \tcode{unordered_set} and \tcode{unordered_multiset}. +\pnum +The exposition-only alias templates \tcode{iter_key_t}, \tcode{iter_val_t}, and \tcode{iter_to_alloc_t} +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}}% @@ -7315,7 +7491,7 @@ #include namespace std { - // \ref{unord.map}, class template unordered_map + // \ref{unord.map}, class template \tcode{unordered_map} template , @@ -7323,7 +7499,7 @@ class Alloc = allocator>> class unordered_map; - // \ref{unord.multimap}, class template unordered_multimap + // \ref{unord.multimap}, class template \tcode{unordered_multimap} template , @@ -7383,14 +7559,14 @@ #include namespace std { - // \ref{unord.set}, class template unordered_set + // \ref{unord.set}, class template \tcode{unordered_set} template , class Pred = equal_to, class Alloc = allocator> class unordered_set; - // \ref{unord.multiset}, class template unordered_multiset + // \ref{unord.multiset}, class template \tcode{unordered_multiset} template , class Pred = equal_to, @@ -7488,7 +7664,7 @@ using local_iterator = @\impdefx{type of \tcode{unordered_map::local_iterator}}@; // see \ref{container.requirements} using const_local_iterator = @\impdefx{type of \tcode{unordered_map::const_local_iterator}}@; // see \ref{container.requirements} using node_type = @\unspec@; - using insert_return_type = @\textit{INSERT_RETURN_TYPE}@; + using insert_return_type = @\placeholdernc{INSERT_RETURN_TYPE}@; // \ref{unord.map.cnstr}, construct/copy/destroy unordered_map(); @@ -7640,6 +7816,53 @@ void reserve(size_type n); }; + template>, + class Pred = equal_to>, + class Allocator = allocator>> + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_map, iter_value_t, Hash, Pred, + Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator>> + unordered_map(initializer_list>, + typename @\seebelow@::size_type = @\seebelow@, Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_map; + + template + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_map, iter_val_t, + hash>, equal_to>, + Allocator>; + + template + unordered_map(InputIterator, InputIterator, Allocator) + -> unordered_map, iter_val_t, + hash>, equal_to>, + Allocator>; + + template + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_map, iter_val_t, Hash, + equal_to>, Allocator>; + + template + unordered_map(initializer_list>, typename @\seebelow@::size_type, + Allocator) + -> unordered_map, equal_to, Allocator>; + + template + unordered_map(initializer_list>, Allocator) + -> unordered_map, equal_to, Allocator>; + + template + unordered_map(initializer_list>, typename @\seebelow@::size_type, Hash, + Allocator) + -> unordered_map, Allocator>; + template bool operator==(const unordered_map& a, const unordered_map& b); @@ -7655,6 +7878,10 @@ } \end{codeblock} +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_map} deduction guide +refers to the \tcode{size_type} member type of the type deduced by the deduction guide. + \rSec3[unord.map.cnstr]{\tcode{unordered_map} constructors} \indexlibrary{\idxcode{unordered_map}!constructor}% @@ -8035,12 +8262,12 @@ unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_multimap(f, l, n, hasher(), key_equal(), a) { } template - unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, + unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(f, l, n, hf, key_equal(), a) { } unordered_multimap(initializer_list il, size_type n, const allocator_type& a) : unordered_multimap(il, n, hasher(), key_equal(), a) { } - unordered_multimap(initializer_list il, size_type n, const hasher& hf, + unordered_multimap(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(il, n, hf, key_equal(), a) { } ~unordered_multimap(); @@ -8132,6 +8359,55 @@ void reserve(size_type n); }; + template>, + class Pred = equal_to>, + class Allocator = allocator>> + unordered_multimap(InputIterator, InputIterator, + typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap, iter_value_t, Hash, Pred, + Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator>> + unordered_multimap(initializer_list>, + typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap; + + template + unordered_multimap(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_multimap, iter_val_t, + hash>, + equal_to>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, Allocator) + -> unordered_multimap, iter_val_t, + hash>, + equal_to>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, typename @\seebelow@::size_type, Hash, + Allocator) + -> unordered_multimap, iter_val_t, Hash, + equal_to>, Allocator>; + + template + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + Allocator) + -> unordered_multimap, equal_to, Allocator>; + + template + unordered_multimap(initializer_list>, Allocator) + -> unordered_multimap, equal_to, Allocator>; + + template + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_multimap, Allocator>; + template bool operator==(const unordered_multimap& a, const unordered_multimap& b); @@ -8144,10 +8420,13 @@ void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); - } \end{codeblock} +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_multimap} deduction guide +refers to the \tcode{size_type} member type of the type deduced by the deduction guide. + \rSec3[unord.multimap.cnstr]{\tcode{unordered_multimap} constructors} \indexlibrary{\idxcode{unordered_multimap}!constructor}% @@ -8195,7 +8474,7 @@ provided, the number of buckets is \impldef{default number of buckets in \tcode{unordered_multimap}}. Then inserts elements from the range \range{f}{l} -for the first form, or from the range +for the first form, or from the range \range{il.begin()}{il.end()} for the second form. \tcode{max_load_factor()} returns \tcode{1.0}. @@ -8301,7 +8580,7 @@ using local_iterator = @\impdefx{type of \tcode{unordered_set::local_iterator}}@; // see \ref{container.requirements} using const_local_iterator = @\impdefx{type of \tcode{unordered_set::const_local_iterator}}@; // see \ref{container.requirements} using node_type = @\unspec@; - using insert_return_type = @\textit{INSERT_RETURN_TYPE}@; + using insert_return_type = @\placeholdernc{INSERT_RETURN_TYPE}@; // \ref{unord.set.cnstr}, construct/copy/destroy unordered_set(); @@ -8428,6 +8707,43 @@ void reserve(size_type n); }; + template::value_type>, + class Pred = equal_to::value_type>, + class Allocator = allocator::value_type>> + unordered_set(InputIterator, InputIterator, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set::value_type, + Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator> + unordered_set(initializer_list, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set; + + template + unordered_set(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_set::value_type, + hash::value_type>, + equal_to::value_type>, + Allocator>; + + template + unordered_set(InputIterator, InputIterator, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_set::value_type, Hash, + equal_to::value_type>, + Allocator>; + + template + unordered_set(initializer_list, typename @\seebelow@::size_type, Allocator) + -> unordered_set, equal_to, Allocator>; + + template + unordered_set(initializer_list, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_set, Allocator>; + template bool operator==(const unordered_set& a, const unordered_set& b); @@ -8443,6 +8759,11 @@ } \end{codeblock} +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_set} deduction guide +refers to the \tcode{size_type} member type of the primary \tcode{unordered_set} +template. + \rSec3[unord.set.cnstr]{\tcode{unordered_set} constructors} \indexlibrary{\idxcode{unordered_set}!constructor}% @@ -8490,7 +8811,7 @@ provided, the number of buckets is \impldef{default number of buckets in \tcode{unordered_set}}. Then inserts elements from the range \range{f}{l} -for the first form, or from the range +for the first form, or from the range \range{il.begin()}{il.end()} for the second form. \tcode{max_load_factor()} returns \tcode{1.0}. @@ -8600,12 +8921,12 @@ unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_multiset(f, l, n, hasher(), key_equal(), a) { } template - unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, + unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(f, l, n, hf, key_equal(), a) { } unordered_multiset(initializer_list il, size_type n, const allocator_type& a) : unordered_multiset(il, n, hasher(), key_equal(), a) { } - unordered_multiset(initializer_list il, size_type n, const hasher& hf, + unordered_multiset(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(il, n, hf, key_equal(), a) { } ~unordered_multiset(); @@ -8695,6 +9016,43 @@ void reserve(size_type n); }; + template::value_type>, + class Pred = equal_to::value_type>, + class Allocator = allocator::value_type>> + unordered_multiset(InputIterator, InputIterator, @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset::value_type, + Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator> + unordered_multiset(initializer_list, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset; + + template + unordered_multiset(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_multiset::value_type, + hash::value_type>, + equal_to::value_type>, + Allocator>; + + template + unordered_multiset(InputIterator, InputIterator, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_multiset::value_type, Hash, + equal_to::value_type>, + Allocator>; + + template + unordered_multiset(initializer_list, typename @\seebelow@::size_type, Allocator) + -> unordered_multiset, equal_to, Allocator>; + + template + unordered_multiset(initializer_list, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_multiset, Allocator>; + template bool operator==(const unordered_multiset& a, const unordered_multiset& b); @@ -8710,6 +9068,11 @@ } \end{codeblock} +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_multiset} deduction guide +refers to the \tcode{size_type} member type of the primary \tcode{unordered_multiset} +template. + \rSec3[unord.multiset.cnstr]{\tcode{unordered_multiset} constructors} \indexlibrary{\idxcode{unordered_multiset}!constructor}% @@ -8800,6 +9163,16 @@ exception is thrown by the swap of the adaptor's \tcode{Container} or \tcode{Compare} object (if any). +\pnum +A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. +\item It has a \tcode{Compare} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has a \tcode{Container} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has an \tcode{Allocator} template parameter and a type that does not qualify as an allocator is deduced for that parameter. +\item It has both \tcode{Container} and \tcode{Allocator} template parameters, and \tcode{uses_allocator_v} is \tcode{false}. +\end{itemize} + \rSec2[queue.syn]{Header \tcode{} synopsis}% \indextext{\idxhdr{queue}}% \indexlibrary{\idxhdr{queue}} @@ -8810,7 +9183,7 @@ namespace std { template > class queue; template , - class Compare = default_order_t> + class Compare = less> class priority_queue; template @@ -8918,6 +9291,12 @@ { using std::swap; swap(c, q.c); } }; + template + queue(Container) -> queue; + + template + queue(Container, Allocator) -> queue; + template bool operator==(const queue& x, const queue& y); template @@ -9133,7 +9512,7 @@ \begin{codeblock} namespace std { template , - class Compare = default_order_t> + class Compare = less> class priority_queue { public: using value_type = typename Container::value_type; @@ -9175,6 +9554,20 @@ { using std::swap; swap(c, q.c); swap(comp, q.comp); } }; + template + priority_queue(Compare, Container) + -> priority_queue; + + template::value_type>, + class Container = vector::value_type>> + priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container()) + -> priority_queue::value_type, Container, Compare>; + + template + priority_queue(Compare, Container, Allocator) + -> priority_queue; + // no equality is provided template @@ -9454,6 +9847,12 @@ { using std::swap; swap(c, s.c); } }; + template + stack(Container) -> stack; + + template + stack(Container, Allocator) -> stack; + template bool operator==(const stack& x, const stack& y); template diff --git a/source/conversions.tex b/source/conversions.tex index 5fed124708..e88e8d0b2a 100644 --- a/source/conversions.tex +++ b/source/conversions.tex @@ -194,7 +194,8 @@ \pnum \indextext{conversion!array-to-pointer}% -\indextext{decay|see{conversion, array to pointer; conversion, function to pointer}}% +\indextext{decay!array|see{conversion, array to pointer}}% +\indextext{decay!function|see{conversion, function to pointer}}% An lvalue or rvalue of type ``array of \tcode{N} \tcode{T}'' or ``array of unknown bound of \tcode{T}'' can be converted to a prvalue of type ``pointer to \tcode{T}''. @@ -326,7 +327,7 @@ \pnum \begin{note} Function types (including those used in pointer to member function -types) are never cv-qualified~(\ref{dcl.fct}). +types) are never cv-qualified (\ref{dcl.fct}). \end{note} \indextext{conversion!qualification|)} @@ -348,8 +349,8 @@ A prvalue of type \tcode{char16_t}, \tcode{char32_t}, or \tcode{wchar_t}~(\ref{basic.fundamental}) can be converted to a prvalue of the first of the following types that can represent all the values of -its underlying type: \tcode{int}, \tcode{unsigned int}, \tcode{long} -\tcode{int}, \tcode{unsigned long} \tcode{int}, \tcode{long long int}, +its underlying type: \tcode{int}, \tcode{unsigned int}, \tcode{long int}, +\tcode{unsigned long int}, \tcode{long long int}, or \tcode{unsigned long long int}. If none of the types in that list can represent all the values of its underlying type, a prvalue of type \tcode{char16_t}, \tcode{char32_t}, or \tcode{wchar_t} can be converted @@ -361,12 +362,12 @@ fixed~(\ref{dcl.enum}) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range $b_\text{min}$ to $b_\text{max}$ as described in~\ref{dcl.enum}): \tcode{int}, -\tcode{unsigned int}, \tcode{long} \tcode{int}, \tcode{unsigned long} \tcode{int}, +\tcode{unsigned int}, \tcode{long int}, \tcode{unsigned long int}, \tcode{long long int}, or \tcode{unsigned long long int}. If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped enumeration type can be converted to a prvalue of the extended integer type with lowest -integer conversion rank~(\ref{conv.rank}) greater than the rank of \tcode{long} -\tcode{long} in which all the values of the enumeration can be represented. If there are +integer conversion rank~(\ref{conv.rank}) greater than the rank of \tcode{long long} +in which all the values of the enumeration can be represented. If there are two such extended types, the signed one is chosen. \pnum @@ -621,11 +622,11 @@ \item The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size. -\item The rank of \tcode{long} \tcode{long} \tcode{int} shall be greater -than the rank of \tcode{long} \tcode{int}, which shall be greater than +\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} \tcode{int}, which shall be greater than the rank of -\tcode{signed} \tcode{char}. +\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. @@ -633,8 +634,8 @@ \item The rank of any standard integer type shall be greater than the rank of any extended integer type with the same size. -\item The rank of \tcode{char} shall equal the rank of \tcode{signed} -\tcode{char} and \tcode{unsigned} \tcode{char}. +\item The rank of \tcode{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. diff --git a/source/cover-reg.tex b/source/cover-reg.tex index 5037259e2c..1b3e20c473 100644 --- a/source/cover-reg.tex +++ b/source/cover-reg.tex @@ -4,7 +4,7 @@ \thispagestyle{empty} -{\raisebox{.35ex}{\smaller\copyright}}\,ISO 2014 --- All rights reserved +{\raisebox{.35ex}{\smaller\copyright}}\,ISO 2017 --- All rights reserved \vspace{2ex} \begin{flushright} @@ -12,7 +12,7 @@ Date: \reldate -ISO/IEC FDIS 14882 +ISO/IEC DIS 14882 ISO/IEC JTC1 SC22 diff --git a/source/declarations.tex b/source/declarations.tex index 5e023e9f62..4645f6d53b 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -182,7 +182,8 @@ \pnum A \grammarterm{simple-declaration} with an \grammarterm{identifier-list} is called -a \defn{decomposition declaration}~(\ref{dcl.decomp}). The \grammarterm{decl-specifier-seq} shall +a \defn{structured binding declaration}~(\ref{dcl.struct.bind}). +The \grammarterm{decl-specifier-seq} shall contain only the \grammarterm{type-specifier} \tcode{auto}~(\ref{dcl.spec.auto}) and \grammarterm{cv-qualifier}{s}. The \grammarterm{initializer} shall be @@ -198,7 +199,7 @@ contains exactly one \grammarterm{declarator-id}, which is the name declared by that \grammarterm{init-declarator} and hence one of the names declared by the declaration. The -\grammarterm{defining-type-specifiers}~(\ref{dcl.type}) in the +\grammarterm{defining-type-specifier}{s}~(\ref{dcl.type}) in the \grammarterm{decl-specifier-seq} and the recursive \grammarterm{declarator} structure of the \grammarterm{init-declarator} describe a type~(\ref{dcl.meaning}), which is then associated with the name being @@ -336,9 +337,9 @@ \end{bnf} At most one \grammarterm{storage-class-specifier} shall appear in a given -\grammarterm{decl-specifier-seq}, except that \tcode{thread_local} may appear with \tcode{static} or +\grammarterm{decl-specifier-seq}, except that \tcode{thread_local} may appear with \tcode{static} or \tcode{extern}. If \tcode{thread_local} appears in any declaration of -a variable it shall be present in all declarations of that entity. If a +a variable it shall be present in all declarations of that entity. If a \grammarterm{storage-class-specifier} appears in a \grammarterm{decl-specifier-seq}, there can be no \tcode{typedef} specifier in the same \grammarterm{decl-specifier-seq} and @@ -401,8 +402,8 @@ see~\ref{basic.link}. \begin{note} The \tcode{extern} keyword can also be used in -\grammarterm{explicit-instantiation}s and -\grammarterm{linkage-specification}s, but it is not a +\grammarterm{explicit-instantiation}{s} and +\grammarterm{linkage-specification}{s}, but it is not a \grammarterm{storage-class-specifier} in such contexts. \end{note} @@ -492,7 +493,7 @@ \indextext{function|seealso{friend function; member function; inline function; virtual function}} \pnum -\grammarterm{Function-specifiers} +\grammarterm{Function-specifier}{s} can be used only in function declarations. \begin{bnf} @@ -732,7 +733,7 @@ int x; int y; constexpr pixel(int); // OK: declaration -}; +}; constexpr pixel::pixel(int a) : x(a), y(x) // OK: definition { square(x); } @@ -745,8 +746,8 @@ constexpr pixel large(4); // OK: \tcode{square} defined int next(constexpr int x) { // error: not for parameters return x + 1; -} -extern constexpr int memsz; // error: not a definition +} +extern constexpr int memsz; // error: not a definition \end{codeblock} \end{example} @@ -754,7 +755,7 @@ A \tcode{constexpr} specifier used in the declaration of a function that is not a constructor declares that function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. Similarly, a -\tcode{constexpr} specifier used in +\tcode{constexpr} specifier used in a constructor declaration declares that constructor to be a \defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}. @@ -768,10 +769,6 @@ \item it shall not be virtual~(\ref{class.virtual}); -\item -for a defaulted copy/move assignment, the class of which it is a member -shall not have a mutable subobject that is a variant member; - \item its return type shall be a literal type; @@ -799,9 +796,9 @@ \begin{example} \begin{codeblock} -constexpr int square(int x) +constexpr int square(int x) { return x * x; } // OK -constexpr long long_max() +constexpr long long_max() { return 2147483647; } // OK constexpr int abs(int x) { if (x < 0) @@ -834,10 +831,6 @@ \item the class shall not have any virtual base classes; -\item -for a defaulted copy/move constructor, the class shall not have a -mutable subobject that is a variant member; - \item each of the parameter types shall be a literal type; @@ -870,17 +863,17 @@ data members and base class subobjects shall be a constexpr constructor; \item -for a delegating constructor, the target constructor shall be a \tcode{constexpr} +for a delegating constructor, the target constructor shall be a constexpr constructor. \end{itemize} \begin{example} \begin{codeblock} -struct Length { +struct Length { constexpr explicit Length(int i = 0) : val(i) { } -private: - int val; -}; +private: + int val; +}; \end{codeblock} \end{example} @@ -891,7 +884,7 @@ an invocation of the function or constructor could be an evaluated subexpression of a core constant expression~(\ref{expr.const}), or, for a constructor, a constant initializer for some object~(\ref{basic.start.static}), -the program is ill-formed; no diagnostic required. +the program is ill-formed, no diagnostic required. \begin{example} \begin{codeblock} constexpr int f(bool b) @@ -916,22 +909,21 @@ If the instantiated template specialization of a constexpr function template or member function of a class template -would fail to satisfy the requirements for a \tcode{constexpr} +would fail to satisfy the requirements for a constexpr function or constexpr constructor, -that specialization is still a constexpr function or \tcode{constexpr} +that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is -ill-formed; no diagnostic -required. +ill-formed, no diagnostic required. \pnum A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects except that \begin{itemize} \item -a call to a \tcode{constexpr} +a call to a constexpr function can appear in a constant expression~(\ref{expr.const}) and \item copy elision is mandatory in a constant expression~(\ref{class.copy}). @@ -942,10 +934,10 @@ effect on the type of a constexpr function or a constexpr constructor. \begin{example} \begin{codeblock} constexpr int bar(int x, int y) // OK - { return x + y + x*y; } -// ... + { return x + y + x*y; } +// ... int bar(int x, int y) // error: redefinition of \tcode{bar} - { return x * 2 + 3 * y; } + { return x * 2 + 3 * y; } \end{codeblock} \end{example} @@ -960,9 +952,9 @@ shall be a constant expression~(\ref{expr.const}). \begin{example} \begin{codeblock} -struct pixel { - int x, y; -}; +struct pixel { + int x, y; +}; constexpr pixel ur = { 1294, 1024 }; // OK constexpr pixel origin; // error: initializer missing \end{codeblock} @@ -985,7 +977,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 defined by~\ref{dcl.fct.spec} shall +the other rules for inline functions specified in this section shall still be respected. \pnum @@ -1121,14 +1113,14 @@ \grammarterm{type-specifier}{s} are discussed in the rest of this section. \end{note} -\rSec3[dcl.type.cv]{The \grammarterm{cv-qualifiers}}% +\rSec3[dcl.type.cv]{The \grammarterm{cv-qualifier}{s}}% \indextext{specifier!cv-qualifier}% \indextext{initialization!\idxcode{const}}% \indextext{type specifier!\idxcode{const}}% \indextext{type specifier!\idxcode{volatile}} \pnum -There are two \grammarterm{cv-qualifiers}, \tcode{const} and +There are two \grammarterm{cv-qualifier}{s}, \tcode{const} and \tcode{volatile}. Each \grammarterm{cv-qualifier} shall appear at most once in a \grammarterm{cv-qualifier-seq}. If a \grammarterm{cv-qualifier} appears in a \grammarterm{decl-specifier-seq}, the \grammarterm{init-declarator-list} @@ -1205,11 +1197,11 @@ \end{example} \pnum -What constitutes an access to an object that has volatile-qualified type is -\impldef{what constitutes an access to an object that has volatile-qualified type}. -If an attempt is made to refer to an object defined with a -volatile-qualified type through the use of a glvalue with a -non-volatile-qualified type, the behavior is undefined. +The semantics of an access through a volatile glvalue are +\impldef{semantics of an access through a volatile glvalue}. +If an attempt is made to access an object defined with a +volatile-qualified type through the use of a non-volatile glvalue, +the behavior is undefined. \pnum \indextext{type specifier!\idxcode{volatile}}% @@ -1285,17 +1277,14 @@ \indextext{type specifier!\idxcode{decltype}}% \indextext{\idxgram{type-name}}% \indextext{\idxgram{lambda-introducer}}% -The \grammarterm{simple-type-specifier} \tcode{auto} is a placeholder for a type to be -deduced~(\ref{dcl.spec.auto}). +The \grammarterm{simple-type-specifier} \tcode{auto} +is a placeholder for +a type to be deduced~(\ref{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} -is a placeholder for a deduced class type -and shall appear only as a \grammarterm{decl-specifier} -in the \grammarterm{decl-specifier-seq} -of a \grammarterm{simple-declaration}~(\ref{dcl.type.class.deduct}) -or as the \grammarterm{simple-type-specifier} -in an explicit type conversion (functional notation)~(\ref{expr.type.conv}). +is a placeholder for +a deduced class type~(\ref{dcl.type.class.deduct}). The \grammarterm{template-name} shall name a class template that is not an injected-class-name. The other @@ -1313,7 +1302,7 @@ {tab:simple.type.specifiers} {ll} \topline -Specifier(s) & Type \\ \capsep +\hdstyle{Specifier(s)} & \hdstyle{Type} \\ \capsep \grammarterm{type-name} & the type named \\ \grammarterm{simple-template-id} & the type as defined in~\ref{temp.names} \\ \grammarterm{template-name} & placeholder for a type to be deduced\\ @@ -1357,8 +1346,8 @@ \end{simpletypetable} \pnum -When multiple \grammarterm{simple-type-specifiers} are allowed, they can be -freely intermixed with other \grammarterm{decl-specifiers} in any order. +When multiple \grammarterm{simple-type-specifier}{s} are allowed, they can be +freely intermixed with other \grammarterm{decl-specifier}{s} in any order. \begin{note} It is \impldef{signedness of \tcode{char}} whether objects of \tcode{char} type are represented as signed or unsigned quantities. The \tcode{signed} specifier @@ -1370,10 +1359,10 @@ For an expression \tcode{e}, the type denoted by \tcode{decltype(e)} is defined as follows: \begin{itemize} -\item if \tcode{e} is an unparenthesized \grammarterm{id-expression} naming an lvalue or -reference introduced from the \grammarterm{identifier-list} of a decomposition declaration, -\tcode{decltype(e)} is the referenced type as given in the specification of the decomposition -declaration~(\ref{dcl.decomp}); +\item if \tcode{e} is an unparenthesized \grammarterm{id-expression} +naming a structured binding~(\ref{dcl.struct.bind}), +\tcode{decltype(e)} is the referenced type as given in +the specification of the structured binding declaration; \item otherwise, if \tcode{e} is an unparenthesized \grammarterm{id-expression} or an unparenthesized @@ -1421,7 +1410,7 @@ \begin{note} As a result, storage is not allocated for the prvalue and it is not destroyed. Thus, a class type is not instantiated -as a result of being the type of a function call in this context. +as a result of being the type of a function call in this context. In this context, the common purpose of writing the expression is merely to refer to its type. In that sense, a \grammarterm{decltype-specifier} is analogous to a use of a \grammarterm{typedef-name}, @@ -1556,9 +1545,9 @@ from an initializer. The \tcode{auto} \grammarterm{type-specifier} is also used to introduce a function type having a \grammarterm{trailing-return-type} or to -signify that a lambda is a generic lambda (\ref{expr.prim.lambda}). +signify that a lambda is a generic lambda (\ref{expr.prim.lambda.closure}). The \tcode{auto} \grammarterm{type-specifier} is also used to introduce a -decomposition declaration (\ref{dcl.decomp}). +structured binding declaration (\ref{dcl.struct.bind}). \pnum The placeholder type can appear with a function declarator in the @@ -1578,7 +1567,7 @@ \grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} of a \grammarterm{parameter-declaration} of a \grammarterm{lambda-expression}, the \indextext{generic lambda!definition of}% -lambda is a \term{generic lambda}~(\ref{expr.prim.lambda}). \begin{example} +lambda is a \term{generic lambda}~(\ref{expr.prim.lambda.closure}). \begin{example} \begin{codeblock} auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda \end{codeblock} @@ -1586,20 +1575,22 @@ \pnum The type of a variable declared using \tcode{auto} or \tcode{decltype(auto)} is -deduced from its initializer. This use is allowed when declaring variables in a -block~(\ref{stmt.block}), in -namespace scope~(\ref{basic.scope.namespace}), and in an -\grammarterm{init-statement} (Clause~\ref{stmt.stmt}). +deduced from its initializer. +This use is allowed +in an initializing declaration~(\ref{dcl.init}) of a variable. \tcode{auto} or \tcode{decltype(auto)} shall appear as one of the \grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} and the \grammarterm{decl-specifier-seq} -shall be followed by one or more \grammarterm{init-declarator}{s}, each of which shall -have a non-empty \grammarterm{initializer}. In an -\grammarterm{initializer} of the form +shall be followed by one or more +\grammarterm{declarator}{s}, +each of which shall +be followed by a non-empty +\grammarterm{initializer}. +In an \grammarterm{initializer} of the form \begin{codeblock} -( @\grammarterm{expression-list}@ ) +( @\textrm{\grammarterm{expression-list}}@ ) \end{codeblock} the \grammarterm{expression-list} shall be a single @@ -1617,15 +1608,10 @@ \end{example} \pnum -A placeholder type can also be used in declaring a variable in -the \grammarterm{condition} of a selection statement~(\ref{stmt.select}) or an iteration -statement~(\ref{stmt.iter}), in the \grammarterm{type-specifier-seq} in +A placeholder type can also be used +in the \grammarterm{type-specifier-seq} in the \grammarterm{new-type-id} or \grammarterm{type-id} of a -\grammarterm{new-expression}~(\ref{expr.new}), in a -\grammarterm{for-range-declaration}, -in declaring a static data member with a -\grammarterm{brace-or-equal-initializer} that appears within the -\grammarterm{member-specification} of a class definition~(\ref{class.static.data}), +\grammarterm{new-expression}~(\ref{expr.new}) and as a \grammarterm{decl-specifier} of the \grammarterm{parameter-declaration}{'s} \grammarterm{decl-specifier-seq} @@ -1874,21 +1860,29 @@ If a placeholder for a deduced class type appears as a \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} -of a \grammarterm{simple-declaration}, -the \grammarterm{init-declarator} -of that declaration -shall be of the form - -\begin{ncbnf} - declarator-id attribute-specifier-seq\opt{} initializer -\end{ncbnf} - -The placeholder is replaced by the return type +of an initializing declaration~(\ref{dcl.init}) of a variable, +the placeholder is replaced by the return type of the function selected by overload resolution for class template deduction~(\ref{over.match.class.deduct}). -If the \grammarterm{init-declarator-list} -contains more than one \grammarterm{init-declarator}, +If the \grammarterm{decl-specifier-seq} +is followed by an \grammarterm{init-declarator-list} +or \grammarterm{member-declarator-list} +containing more than one \grammarterm{declarator}, the type that replaces the placeholder shall be the same in each deduction. + +\pnum +A placeholder for a deduced class type +can also be used +in the \grammarterm{type-specifier-seq} +in the \grammarterm{new-type-id} or \grammarterm{type-id} +of a \grammarterm{new-expression}~(\ref{expr.new}), +or +as the \grammarterm{simple-type-specifier} +in an explicit type conversion (functional notation)~(\ref{expr.type.conv}). +A placeholder for a deduced class type +shall not appear in any other context. + +\pnum \begin{example} \begin{codeblock} template struct container { @@ -1975,7 +1969,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} \grammarterm{nested-name-specifier}\opt{} \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 @@ -2112,7 +2106,7 @@ integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed. It is \impldef{underlying type for enumeration} -which integral type is used as the underlying type +which integral type is used as the underlying type except that the underlying type shall not be larger than \tcode{int} unless the value of an enumerator cannot fit in an \tcode{int} or \tcode{unsigned int}. If the \grammarterm{enumerator-list} is empty, the @@ -2189,20 +2183,20 @@ These names obey the scope rules defined for all names in~\ref{basic.scope} and~\ref{basic.lookup}. \begin{example} \begin{codeblock} -enum direction { left='l', right='r' }; +enum direction { left='l', right='r' }; -void g() { - direction d; // OK - d = left; // OK - d = direction::right; // OK -} +void g() { + direction d; // OK + d = left; // OK + d = direction::right; // OK +} -enum class altitude { high='h', low='l' }; +enum class altitude { high='h', low='l' }; -void h() { - altitude a; // OK - a = high; // error: \tcode{high} not in scope - a = altitude::low; // OK +void h() { + altitude a; // OK + a = high; // error: \tcode{high} not in scope + a = altitude::low; // OK } \end{codeblock} \end{example} @@ -2323,7 +2317,7 @@ Because a \grammarterm{namespace-definition} contains \grammarterm{declaration}{s} in its \grammarterm{namespace-body} and a \grammarterm{namespace-definition} is itself a \grammarterm{declaration}, it -follows that \grammarterm{namespace-definitions} can be nested. +follows that \grammarterm{namespace-definition}{s} can be nested. \begin{example} \begin{codeblock} namespace Outer { @@ -2365,7 +2359,7 @@ \grammarterm{namespace-definition} for a particular namespace, that namespace is declared to be an \term{inline namespace}. The \tcode{inline} keyword may be used on a \grammarterm{namespace-definition} that extends a namespace -only if it was previously used on the \grammarterm{namespace-definition} +only if it was previously used on the \grammarterm{namespace-definition} that initially declared the \grammarterm{namespace-name} for that namespace. \pnum @@ -2479,7 +2473,7 @@ whose \grammarterm{class-head-name} (Clause \ref{class}) or \grammarterm{enum-head-name}~(\ref{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}~(\ref{dcl.type.elab}), or +\grammarterm{attribute-specifier-seq}\opt{} \grammarterm{identifier}~(\ref{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}. @@ -3339,11 +3333,13 @@ \begin{bnf} \nontermdef{asm-definition}\br - \terminal{asm (} string-literal \terminal{) ;} + attribute-specifier-seq\opt{} \terminal{asm (} string-literal \terminal{) ;} \end{bnf} The \tcode{asm} declaration is conditionally-supported; its meaning is \impldef{meaning of \tcode{asm} declaration}. +The optional \grammarterm{attribute-specifier-seq} in +an \grammarterm{asm-definition} appertains to the \tcode{asm} declaration. \begin{note} Typically it is used to pass information through the implementation to an assembler. @@ -3699,7 +3695,7 @@ \grammarterm{attribute}'s specification permits it. An \grammarterm{attribute} followed by an ellipsis is a pack expansion~(\ref{temp.variadic}). An \grammarterm{attribute-specifier} that contains no \grammarterm{attribute}{s} has no -effect. The order in which the \grammarterm{attribute-tokens} appear in an +effect. The order in which the \grammarterm{attribute-token}{s} appear in an \grammarterm{attribute-list} is not significant. If a keyword~(\ref{lex.key}) or an alternative token~(\ref{lex.digraph}) that satisfies the syntactic requirements @@ -3715,7 +3711,7 @@ statement, identified by the syntactic context where it appears (Clause~\ref{stmt.stmt}, Clause~\ref{dcl.dcl}, Clause~\ref{dcl.decl}). If an \grammarterm{attribute-specifier-seq} that appertains to some -entity or statement contains an \grammarterm{attribute} that +entity or statement contains an \grammarterm{attribute} or \grammarterm{alignment-specifier} that is not allowed to apply to that entity or statement, the program is ill-formed. If an \grammarterm{attribute-specifier-seq} appertains to a friend declaration~(\ref{class.friend}), that declaration shall be a @@ -3827,7 +3823,7 @@ struct S { int x; } s, *p = &s; // Translation unit \#2: -struct alignas(16) S; // error: definition of \tcode{S} lacks alignment; no diagnostic required +struct alignas(16) S; // error: definition of \tcode{S} lacks alignment, no diagnostic required extern S* p; \end{codeblock} \end{example} @@ -3881,7 +3877,7 @@ parameters is declared with the \tcode{carries_dependency} attribute in its first declaration in one translation unit and the same function or one of its parameters is declared without the \tcode{carries_dependency} attribute in its first declaration in another translation unit, the -program is ill-formed; no diagnostic required. +program is ill-formed, no diagnostic required. \pnum \begin{note} The \tcode{carries_dependency} attribute does not change the meaning of the @@ -3969,7 +3965,7 @@ A name or entity declared without the \tcode{deprecated} attribute can later be redeclared with the attribute and vice-versa. \begin{note} Thus, an entity initially declared without the attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity -is marked as deprecated, later redeclarations do not un-deprecate the entity. \end{note} +is marked as deprecated, later redeclarations do not un-deprecate the entity. \end{note} Redeclarations using different forms of the attribute (with or without the \grammarterm{attribute-argument-clause} or with different \grammarterm{attribute-argument-clause}{s}) are allowed. @@ -4104,7 +4100,8 @@ launch_missiles(); } error_info &foo(); -void f() { foo(); } // reference type, warning not encouraged +void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither + // the (reference) return type nor the function is declared nodiscard \end{codeblock} \end{example} @@ -4119,7 +4116,7 @@ specify the \tcode{noreturn} attribute if any declaration of that function specifies the \tcode{noreturn} attribute. If a function is declared with the \tcode{noreturn} attribute in one translation unit and the same function is declared without the \tcode{noreturn} attribute in another -translation unit, the program is ill-formed; no diagnostic required. +translation unit, the program is ill-formed, no diagnostic required. \pnum If a function \tcode{f} is called where \tcode{f} was previously declared with the \tcode{noreturn} diff --git a/source/declarators.tex b/source/declarators.tex index 0dff1ac97b..5c884c27cb 100644 --- a/source/declarators.tex +++ b/source/declarators.tex @@ -70,8 +70,8 @@ and each \tcode{Di} is an \grammarterm{init-declarator}. One exception is when a name introduced by one of the \grammarterm{declarator}{s} hides a type name used by the -\grammarterm{decl-specifiers}, so that when the same -\grammarterm{decl-specifiers} are used in a subsequent declaration, +\grammarterm{decl-specifier}{s}, so that when the same +\grammarterm{decl-specifier}{s} are used in a subsequent declaration, they do not have the same meaning, as in \begin{codeblock} struct S { ... }; @@ -255,7 +255,7 @@ \pnum A type can also be named (often more easily) by using a -\grammarterm{typedef} +\tcode{typedef} (\ref{dcl.typedef}). \rSec1[dcl.ambig.res]{Ambiguity resolution}% @@ -325,14 +325,7 @@ \pnum Another ambiguity arises in a -\grammarterm{parameter-declaration-clause} -of a function declaration, or in a -\grammarterm{type-id} -that is the operand of a -\tcode{sizeof} -or -\tcode{typeid} -operator, when a +\grammarterm{parameter-declaration-clause} when a \grammarterm{type-name} is nested in parentheses. In this case, the choice is between the declaration of a parameter of type @@ -439,7 +432,7 @@ where \tcode{T} -is of the form \grammarterm{attribute-specifier-seq\opt} +is of the form \grammarterm{attribute-specifier-seq}\opt{} \grammarterm{decl-specifier-seq} and \tcode{D} @@ -481,7 +474,7 @@ \pnum In a declaration -\grammarterm{attribute-specifier-seq\opt} +\grammarterm{attribute-specifier-seq}\opt{} \tcode{T} \tcode{D} where @@ -850,7 +843,7 @@ is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to member of class \grammarterm{nested-name-specifier} of type \tcode{T}''. -The optional \grammarterm{attribute-specifier-seq}~(\ref{dcl.attr.grammar}) appertains to the +The optional \grammarterm{attribute-specifier-seq}~(\ref{dcl.attr.grammar}) appertains to the pointer-to-member. \pnum @@ -966,7 +959,7 @@ If the \grammarterm{constant-expression} (\ref{expr.const}) is present, it shall be a converted constant -expression of type \tcode{std\colcol{}size_t} and +expression of type \tcode{std::size_t} and its value shall be greater than zero. The constant expression specifies the \indextext{array!bound}% @@ -1242,12 +1235,10 @@ where \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 \end{ncsimplebnf} - and the type of the contained \grammarterm{declarator-id} in the declaration @@ -1264,8 +1255,8 @@ ``\placeholder{derived-declarator-type-list} \tcode{noexcept}\opt function of -(\grammarterm{parameter-declaration-clause} ) -\grammarterm{cv-qualifier-seq\opt} \grammarterm{ref-qualifier\opt} +(\grammarterm{parameter-declaration-clause}) +\grammarterm{cv-qualifier-seq}\opt{} \grammarterm{ref-qualifier}\opt{} returning \tcode{T}'', where the optional \tcode{noexcept} is present if and only if @@ -2292,15 +2283,16 @@ \end{example}% \indextext{definition!function|)} -\rSec1[dcl.decomp]{Decomposition declarations}% -\indextext{decomposition declaration}% -\indextext{declaration!decomposition|see{decomposition declaration}}% +\rSec1[dcl.struct.bind]{Structured binding declarations}% +\indextext{structured binding declaration}% +\indextext{declaration!structured binding|see{structured binding declaration}}% \pnum -A decomposition declaration introduces the \grammarterm{identifier}{s} +A structured binding declaration introduces the \grammarterm{identifier}{s} \tcode{v}$_0$, \tcode{v}$_1$, \tcode{v}$_2$, ... of the -\grammarterm{identifier-list} as names~(\ref{basic.scope.declarative}). +\grammarterm{identifier-list} as names~(\ref{basic.scope.declarative}), +called \defn{structured binding}{s}. Let \cv{} denote the \grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq}. First, a variable with a unique name \tcode{e} is introduced. If the @@ -2319,7 +2311,8 @@ where the declaration is never interpreted as a function declaration and the parts of the declaration other than the \grammarterm{declarator-id} are taken -from the corresponding decomposition declaration. The type of the \grammarterm{id-expression} +from the corresponding structured binding declaration. +The type of the \grammarterm{id-expression} \tcode{e} is called \tcode{E}. \begin{note} \tcode{E} is never a reference type (Clause~\ref{expr}). @@ -2373,7 +2366,7 @@ \tcode{E} shall not have an anonymous union member, and the number of elements in the \grammarterm{identifier-list} shall be equal to the number of non-static data members of \tcode{E}. -Designating the non-static data members of \tcode{E} as +Designating the non-static data members of \tcode{E} as \tcode{m}$_0$, \tcode{m}$_1$, \tcode{m}$_2$, ... (in declaration order), each \tcode{v}$_i$ is the @@ -2480,9 +2473,8 @@ \indextext{initialization!default}% \indextext{variable!indeterminate uninitialized}% \indextext{initialization!zero-initialization}% -\indextext{zero-initialization}% To -\grammarterm{zero-initialize} +\defnx{zero-initialize}{zero-initialization} an object or reference of type \tcode{T} means: @@ -2505,8 +2497,11 @@ if \tcode{T} is a (possibly cv-qualified) non-union class type, -each non-static data member and each -base-class subobject is zero-initialized and padding is initialized to zero bits; +each non-static data member, +each non-virtual base class subobject, and, +if the object is not a base class subobject, +each virtual base class subobject +is zero-initialized and padding is initialized to zero bits; \item if @@ -2529,9 +2524,8 @@ \end{itemize} \pnum -\indextext{default-initialization}% To -\grammarterm{default-initialize} +\defnx{default-initialize}{default-initialization} an object of type \tcode{T} means: @@ -2584,9 +2578,8 @@ \tcode{T} shall be a const-default-constructible class type or array thereof. \pnum -\indextext{value-initialization}% To -\defn{value-initialize} +\defnx{value-initialize}{value-initialization} an object of type \tcode{T} means: @@ -2673,23 +2666,31 @@ \begin{itemize} \item -If an indeterminate value of unsigned narrow character -type~(\ref{basic.fundamental}) is produced by the evaluation of: +If an indeterminate value of +unsigned narrow character type~(\ref{basic.fundamental}) +or \tcode{std::byte} type~(\ref{cstddef.syn}) +is produced by the evaluation of: \begin{itemize} \item the second or third operand of a conditional expression~(\ref{expr.cond}), \item the right operand of a comma expression~(\ref{expr.comma}), -\item the operand of a cast or conversion to an unsigned narrow character -type~(\ref{conv.integral}, \ref{expr.type.conv}, \ref{expr.static.cast}, -\ref{expr.cast}), or +\item the operand of a cast or conversion~(\ref{conv.integral}, +\ref{expr.type.conv}, \ref{expr.static.cast}, \ref{expr.cast}) to an +unsigned narrow character type +or \tcode{std::byte} type~(\ref{cstddef.syn}), or \item a discarded-value expression (Clause~\ref{expr}), \end{itemize} then the result of the operation is an indeterminate value. \item -If an indeterminate value of unsigned narrow character -type is produced by the evaluation of the right +If an indeterminate value of +unsigned narrow character type +or \tcode{std::byte} type +is produced by the evaluation of the right operand of a simple assignment operator~(\ref{expr.ass}) whose first operand -is an lvalue of unsigned narrow character type, an indeterminate value replaces +is an lvalue of +unsigned narrow character type +or \tcode{std::byte} type, +an indeterminate value replaces the value of the object referred to by the left operand. \item @@ -2697,6 +2698,15 @@ evaluation of the initialization expression when initializing an object of unsigned narrow character type, that object is initialized to an indeterminate value. + +\item +If an indeterminate value of +unsigned narrow character type +or \tcode{std::byte} type +is produced by the +evaluation of the initialization expression when initializing an object of +\tcode{std::byte} type, that object is initialized to an indeterminate +value. \end{itemize} \begin{example} \begin{codeblock} @@ -2760,7 +2770,7 @@ \grammarterm{mem-initializer}{s}~(\ref{class.base.init}), and the \grammarterm{braced-init-list} form of a \grammarterm{condition} is called -\grammarterm{direct-initialization}. +\defn{direct-initialization}. \pnum The semantics of initializers are as follows. @@ -2893,6 +2903,19 @@ or by an inherited constructor~(\ref{class.inhctor.init}). \end{note} +\pnum +A declaration that specifies the initialization of a variable, +whether from an explicit initializer or by default-initialization, +is called the \defn{initializing declaration} of that variable. +\begin{note} +In most cases +this is the defining declaration~(\ref{basic.def}) of the variable, +but the initializing declaration +of a non-inline static data member~(\ref{class.static.data}) +might be the declaration within the class definition +and not the definition at namespace scope. +\end{note} + \rSec2[dcl.init.aggr]{Aggregates}% \indextext{aggregate}% \indextext{initialization!aggregate}% @@ -2926,8 +2949,9 @@ \item for an array, the array elements in increasing subscript order, or \item -for a class, the direct base classes in declaration order -followed by the direct non-static data members in declaration order. +for a class, the direct base classes in declaration order, +followed by the direct non-static data members~(\ref{class.mem}) +that are not members of an anonymous union, in declaration order. \end{itemize} \pnum @@ -3063,7 +3087,7 @@ An \grammarterm{initializer-list} is ill-formed if the number of -\grammarterm{initializer-clause}{s} +\grammarterm{initializer-clause}{s} exceeds the number of elements to initialize. \begin{example} @@ -3076,10 +3100,27 @@ \pnum If there are fewer \grammarterm{initializer-clause}{s} in the list than there -are elements in the aggregate, then each element not explicitly initialized -shall be initialized from its default member initializer~(\ref{class.mem}) or, -if there is no default member initializer, from an empty -initializer list~(\ref{dcl.init.list}). +are elements in a non-union aggregate, then each element not explicitly initialized +is initialized as follows: +\begin{itemize} +\item +If the element has a default member initializer~(\ref{class.mem}), +the element is initialized from that initializer. +\item +Otherwise, if the element is not a reference, the element +is copy-initialized from an empty initializer list~(\ref{dcl.init.list}). +\item +Otherwise, the program is ill-formed. +\end{itemize} +If the aggregate is a union and the initializer list is empty, then +\begin{itemize} +\item +if any variant member has a default member initializer, +that member is initialized from its default member initializer; +\item +otherwise, the first member of the union (if any) +is copy-initialized from an empty initializer list. +\end{itemize} \begin{example} \begin{codeblock} @@ -3150,11 +3191,6 @@ \end{codeblock} \end{example} -\pnum -If an incomplete or empty -\grammarterm{initializer-list} -leaves a member of reference type uninitialized, the program is ill-formed. - \pnum When initializing a multi-dimensional array, the @@ -3615,7 +3651,7 @@ If \tcode{T1} or \tcode{T2} is a class type and \tcode{T1} is not reference-related to \tcode{T2}, user-defined conversions are considered -using the rules for copy-initialization of an object of type +using the rules for copy-initialization of an object of type ``\cvqual{cv1} \tcode{T1}'' by user-defined conversion (\ref{dcl.init}, \ref{over.match.copy}, \ref{over.match.conv}); @@ -3691,14 +3727,14 @@ \indextext{initialization!list-initialization|(} \pnum -\grammarterm{List-initialization} is initialization of an object or reference from a +\defnx{List-initialization}{list-initialization} is initialization of an object or reference from a \grammarterm{braced-init-list}. Such an initializer is called an \term{initializer list}, and the comma-separated \grammarterm{initializer-clause}{s} of the list are called the \term{elements} of the initializer list. An initializer list may be empty. List-initialization can occur in direct-initialization or copy-initialization contexts; list-initialization in a direct-initialization context is called -\grammarterm{direct-list-initialization} and list-initialization in a -copy-initialization context is called \grammarterm{copy-list-initialization}. \begin{note} +\defn{direct-list-initialization} and list-initialization in a +copy-initialization context is called \defn{copy-list-initialization}. \begin{note} List-initialization can be used \begin{itemize} @@ -3722,20 +3758,20 @@ f( {"Nicholas","Annemarie"} ); // pass list of two elements return { "Norah" }; // return list of one element int* e {}; // initialization to zero / null pointer -x = double{1}; // explicitly construct a double +x = double{1}; // explicitly construct a \tcode{double} std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; \end{codeblock} \end{example} \end{note} \pnum -A constructor is an \grammarterm{initializer-list constructor} if its first parameter is +A constructor is an \defn{initializer-list constructor} if its first parameter is of type \tcode{std::initializer_list} or reference to possibly cv-qualified \tcode{std::initializer_list} for some type \tcode{E}, and either there are no other parameters or else all other parameters have default arguments (\ref{dcl.fct.default}). \begin{note} Initializer-list constructors are favored over other constructors in list-initialization~(\ref{over.match.list}). Passing an initializer list as the argument to the constructor template \tcode{template C(T)} of a class \tcode{C} does not -create an initializer-list constructor, because an initializer list argument causes the +create an initializer-list constructor, because an initializer list argument causes the corresponding parameter to be a non-deduced context~(\ref{temp.deduct.call}). \end{note} The template \tcode{std::initializer_list} is not predefined; if the header @@ -3825,6 +3861,33 @@ \end{codeblock} \end{example} +\item Otherwise, if \tcode{T} is an enumeration +with a fixed underlying type~(\ref{dcl.enum}), +the \grammarterm{initializer-list} has a single element \tcode{v}, and +the initialization is direct-list-initialization, +the object is initialized with the value \tcode{T(v)}~(\ref{expr.type.conv}); +if a narrowing conversion is required to convert \tcode{v} +to the underlying type of \tcode{T}, the program is ill-formed. +\begin{example} +\begin{codeblock} +enum byte : unsigned char { }; +byte b { 42 }; // OK +byte c = { 42 }; // error +byte d = byte{ 42 }; // OK; same value as \tcode{b} +byte e { -1 }; // error + +struct A { byte b; }; +A a1 = { { 42 } }; // error +A a2 = { byte{ 42 } }; // OK + +void f(byte); +f({ 42 }); // error + +enum class Handle : uint32_t { Invalid = 0 }; +Handle h { 42 }; // OK +\end{codeblock} +\end{example} + \item Otherwise, if the initializer list has a single element of type \tcode{E} and either \tcode{T} is not a reference type or its referenced type is @@ -3866,34 +3929,6 @@ \end{codeblock} \end{example} -\item Otherwise, if \tcode{T} is an enumeration -with a fixed underlying type~(\ref{dcl.enum}), -the \grammarterm{initializer-list} has a single element \tcode{v}, and -the initialization is direct-list-initialization, -the object is initialized with the value \tcode{T(v)}~(\ref{expr.type.conv}); -if a narrowing conversion is required to convert \tcode{v} -to the underlying type of \tcode{T}, the program is ill-formed. - -\begin{example} -\begin{codeblock} -enum byte : unsigned char { }; -byte b { 42 }; // OK -byte c = { 42 }; // error -byte d = byte{ 42 }; // OK; same value as \tcode{b} -byte e { -1 }; // error - -struct A { byte b; }; -A a1 = { { 42 } }; // error -A a2 = { byte{ 42 } }; // OK - -void f(byte); -f({ 42 }); // error - -enum class Handle : uint32_t { Invalid = 0 }; -Handle h { 42 }; // OK -\end{codeblock} -\end{example} - \item Otherwise, if the initializer list has no elements, the object is value-initialized. @@ -3908,7 +3943,7 @@ \begin{example} \begin{codeblock} struct A { int i; int j; }; -A a1 { 1, 2 }; // aggregate initialization +A a1 { 1, 2 }; // aggregate initialization A a2 { 1.2 }; // error: narrowing struct B { B(std::initializer_list); @@ -3918,7 +3953,7 @@ struct C { C(int i, double j); }; -C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2) +C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2) C c2 = { 1.1, 2 }; // error: narrowing int j { 1 }; // initialize to 1 @@ -4035,7 +4070,7 @@ list-initializations.\end{note} \begin{example} \begin{codeblock} -int x = 999; // x is not a constant expression +int x = 999; // \tcode{x} is not a constant expression const int y = 999; const int z = 99; char c1 = x; // OK, though it might narrow (in this case, it does narrow) @@ -4049,10 +4084,10 @@ { (unsigned int)-1 }; // error: narrows int ii = {2.0}; // error: narrows float f1 { x }; // error: might narrow -float f2 { 7 }; // OK: 7 can be exactly represented as a float +float f2 { 7 }; // OK: 7 can be exactly represented as a \tcode{float} int f(int); int a[] = - { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level + { 2, f(2), f(2.0) }; // OK: the \tcode{double}-to-\tcode{int} conversion is not at the top level \end{codeblock} \end{example}% \indextext{initialization!list-initialization|)}% diff --git a/source/derived.tex b/source/derived.tex index ad0c0b2188..29ed414d82 100644 --- a/source/derived.tex +++ b/source/derived.tex @@ -29,22 +29,18 @@ \begin{bnf} \nontermdef{base-specifier}\br - attribute-specifier-seq\opt base-type-specifier\br - attribute-specifier-seq\opt{} \terminal{virtual} access-specifier\opt base-type-specifier\br - attribute-specifier-seq\opt access-specifier \terminal{virtual}\opt base-type-specifier + 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 \end{bnf} \begin{bnf} \nontermdef{class-or-decltype}\br nested-name-specifier\opt class-name\br + nested-name-specifier \terminal{template} simple-template-id\br decltype-specifier \end{bnf} -\begin{bnf} -\nontermdef{base-type-specifier}\br - class-or-decltype -\end{bnf} - \indextext{specifier access|see{access specifier}}% % \begin{bnf} @@ -58,10 +54,11 @@ \pnum \indextext{type!incomplete}% -The type denoted by a \grammarterm{base-type-specifier} shall be +A \grammarterm{class-or-decltype} shall denote a class type that is not -an -incompletely defined class (Clause~\ref{class}); this class is called a +an incompletely defined class (Clause~\ref{class}). +The class denoted by the \grammarterm{class-or-decltype} of +a \grammarterm{base-specifier} is called a \indextext{base class!direct}% \term{direct base class} for the class being defined. @@ -231,9 +228,9 @@ \pnum \indextext{base class!virtual}% A base class specifier that does not contain the keyword -\tcode{virtual}, specifies a \grammarterm{non-virtual} base class. A base -class specifier that contains the keyword \tcode{virtual}, specifies a -\term{virtual} base class. For each distinct occurrence of a +\tcode{virtual} specifies a \defnx{non-virtual base class}{base class!non-virtual}. A base +class specifier that contains the keyword \tcode{virtual} specifies a +\defnx{virtual base class}{base class!virtual}. For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object~(\ref{intro.object}) shall contain a corresponding distinct base class subobject of that type. For each @@ -707,7 +704,7 @@ \begin{itemize} \item both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes\footnote{Multi-level pointers to classes or references to multi-level pointers to -classes are not allowed.% +classes are not allowed.% } \item the class in the return type of \tcode{B::f} is the same class as diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 5b411857bf..b30f0fe6dc 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -752,7 +752,7 @@ #define ETIMEDOUT @\seebelow@ #define ETXTBSY @\seebelow@ #define EWOULDBLOCK @\seebelow@ -#define EXDEV @\seebelow@ +#define EXDEV @\seebelow@ \end{codeblock} \pnum @@ -880,7 +880,7 @@ value_too_large, // \tcode{EOVERFLOW} wrong_protocol_type, // \tcode{EPROTOTYPE} }; - + template <> struct is_error_condition_enum : true_type {}; // \ref{syserr.errcode.nonmembers}, non-member functions @@ -911,9 +911,9 @@ template <> struct hash; // \ref{syserr}, system error support - template constexpr bool is_error_code_enum_v + template inline constexpr bool is_error_code_enum_v = is_error_code_enum::value; - template constexpr bool is_error_condition_enum_v + template inline constexpr bool is_error_condition_enum_v = is_error_condition_enum::value; } \end{codeblock} @@ -962,7 +962,7 @@ virtual bool equivalent(int code, const error_condition& condition) const noexcept; virtual bool equivalent(const error_code& code, int condition) const noexcept; virtual string message(int ev) const = 0; - + bool operator==(const error_category& rhs) const noexcept; bool operator!=(const error_category& rhs) const noexcept; bool operator<(const error_category& rhs) const noexcept; @@ -1187,7 +1187,7 @@ // \ref{syserr.errcode.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; template - error_code& operator=(ErrorCodeEnum e) noexcept; + error_code& operator=(ErrorCodeEnum e) noexcept; void clear() noexcept; // \ref{syserr.errcode.observers}, observers @@ -1253,7 +1253,7 @@ \postconditions \tcode{*this == make_error_code(e)}. \pnum -\remarks This constructor shall not participate in overload resolution unless\linebreak +\remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak \tcode{is_error_code_enum_v} is \tcode{true}. \end{itemdescr} @@ -1283,7 +1283,7 @@ \returns \tcode{*this}. \pnum -\remarks This operator shall not participate in overload resolution unless\linebreak +\remarks \raggedright This operator shall not participate in overload resolution unless\linebreak \tcode{is_error_code_enum_v} is \tcode{true}. \end{itemdescr} @@ -1399,7 +1399,7 @@ // \ref{syserr.errcondition.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; template - error_condition& operator=(ErrorConditionEnum e) noexcept; + error_condition& operator=(ErrorConditionEnum e) noexcept; void clear() noexcept; // \ref{syserr.errcondition.observers}, observers @@ -1457,7 +1457,7 @@ \postconditions \tcode{*this == make_error_condition(e)}. \pnum -\remarks This constructor shall not participate in overload resolution unless\linebreak +\remarks \raggedright This constructor shall not participate in overload resolution unless\linebreak \tcode{is_error_condition_enum_v} is \tcode{true}. \end{itemdescr} @@ -1488,7 +1488,7 @@ \returns \tcode{*this}. \pnum -\remarks This operator shall not participate in overload resolution unless\linebreak +\remarks \raggedright This operator shall not participate in overload resolution unless\linebreak \tcode{is_error_condition_enum_v} is \tcode{true}. \end{itemdescr} @@ -1663,10 +1663,11 @@ application program interfaces. \pnum -\begin{note} If an error represents an out-of-memory condition, implementations are -encouraged to throw an exception object of type \tcode{bad_alloc}~\ref{bad.alloc} rather -than \tcode{system_error}. \end{note} - +\begin{note} +If an error represents an out-of-memory condition, implementations are +encouraged to throw an exception object of type \tcode{bad_alloc}~(\ref{bad.alloc}) rather +than \tcode{system_error}. +\end{note} \indexlibrary{\idxcode{system_error}}% \begin{codeblock} namespace std { @@ -1675,10 +1676,8 @@ system_error(error_code ec, const string& what_arg); system_error(error_code ec, const char* what_arg); system_error(error_code ec); - system_error(int ev, const error_category& ecat, - const string& what_arg); - system_error(int ev, const error_category& ecat, - const char* what_arg); + system_error(int ev, const error_category& ecat, const string& what_arg); + system_error(int ev, const error_category& ecat, const char* what_arg); system_error(int ev, const error_category& ecat); const error_code& code() const noexcept; const char* what() const noexcept override; @@ -1733,8 +1732,7 @@ \indexlibrary{\idxcode{system_error}!constructor}% \begin{itemdecl} -system_error(int ev, const error_category& ecat, - const string& what_arg); +system_error(int ev, const error_category& ecat, const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -1749,8 +1747,7 @@ \indexlibrary{\idxcode{system_error}!constructor}% \begin{itemdecl} -system_error(int ev, const error_category& ecat, - const char* what_arg); +system_error(int ev, const error_category& ecat, const char* what_arg); \end{itemdecl} \begin{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index 5778f10cb3..605371f2e2 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -73,15 +73,15 @@ \begin{example} \begin{codeblock} void f() { - goto l1; // Ill-formed - goto l2; // Ill-formed + goto l1; // ill-formed + goto l2; // ill-formed try { goto l1; // OK - goto l2; // Ill-formed + goto l2; // ill-formed l1: ; } catch (...) { l2: ; - goto l1; // Ill-formed + goto l1; // ill-formed goto l2; // OK } } @@ -173,12 +173,9 @@ C::C(int ii, double id) try : i(f(ii)), d(id) { // constructor statements +} catch (...) { + // handles exceptions thrown from the ctor-initializer and from the constructor statements } -catch (...) { - // handles exceptions thrown from the ctor-initializer - // and from the constructor statements -} - \end{codeblock} \end{example} @@ -216,8 +213,7 @@ \begin{codeblock} try { // ... -} -catch(const char* p) { +} catch(const char* p) { // handle character string exceptions here } \end{codeblock} @@ -233,7 +229,7 @@ } \end{codeblock} can be caught by a handler for exceptions of type -\tcode{Overflow} +\tcode{Overflow}: \begin{codeblock} try { f(1.2); @@ -389,10 +385,10 @@ A a; Y y; A b; - return {}; // \#1 + return {}; // \#1 } catch (...) { } - return {}; // \#2 + return {}; // \#2 } \end{codeblock} At \#1, the returned object of type \tcode{A} is constructed. @@ -410,7 +406,7 @@ is terminated by an exception, the destructor is invoked for each of the object's direct subobjects -and, for a complete object, virtual base class subobjects, +and, for a complete object, virtual base class subobjects, whose initialization has completed~(\ref{dcl.init}) and whose destructor has not yet begun execution, except that in the case of destruction, the variant members of a @@ -493,7 +489,7 @@ The \grammarterm{handler} is of type \cv{}~\tcode{T} or \cv{}~\tcode{T\&} and \tcode{E} and \tcode{T} -are the same type (ignoring the top-level \grammarterm{cv-qualifiers}), or +are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or \item% the \grammarterm{handler} is of type \cv{}~\tcode{T} or \cv{}~\tcode{T\&} and @@ -540,9 +536,9 @@ try { g(); } catch (Overflow oo) { - // ... + // ... } catch (Matherr mm) { - // ... + // ... } } \end{codeblock} @@ -716,7 +712,7 @@ if supplied, shall be a contextually converted constant expression of type \tcode{bool}~(\ref{expr.const}); that constant expression is the exception specification of -the function type in which the \grammarterm{noexcept-specifier} appears. +the function type in which the \grammarterm{noexcept-specifier} appears. A \tcode{(} token that follows \tcode{noexcept} is part of the \grammarterm{noexcept-specifier} and does not commence an initializer~(\ref{dcl.init}). @@ -799,18 +795,18 @@ \end{note} \begin{example} \begin{codeblock} -extern void f(); // potentially-throwing +extern void f(); // potentially-throwing void g() noexcept { - f(); // valid, even if \tcode{f} throws - throw 42; // valid, effectively a call to \tcode{std::terminate} + f(); // valid, even if \tcode{f} throws + throw 42; // valid, effectively a call to \tcode{std::terminate} } \end{codeblock} The call to \tcode{f} is well-formed even though, when called, \tcode{f} -might throw exception. +might throw an exception. \end{example} \pnum @@ -914,7 +910,7 @@ }; struct B { B() throw(); - B(const B&) = default; // implicit exception specification is \tcode{noexcept(true)} + B(const B&) = default; // implicit exception specification is \tcode{noexcept(true)} B(B&&, int = (throw Y(), 0)) noexcept; ~B() noexcept(false); }; diff --git a/source/expressions.tex b/source/expressions.tex index 65a8f5910c..7b7dfabbb2 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -165,8 +165,8 @@ are performed; if the other operand does not have the same type, the expression is ill-formed. -\item If either operand is of type \tcode{long} \tcode{double}, the -other shall be converted to \tcode{long} \tcode{double}. +\item 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}. @@ -288,9 +288,10 @@ \item if \tcode{T1} or \tcode{T2} is ``pointer to \cvqual{cv1} \tcode{void}'' and the -other type is ``pointer to \cvqual{cv2} T'', ``pointer to \cvqual{cv12} -\tcode{void}'', where \cvqual{cv12} is the union of \cvqual{cv1} -and \cvqual{cv2}; +other type is ``pointer to \cvqual{cv2} T'', +where \tcode{T} is an object type or \tcode{void}, +``pointer to \cvqual{cv12} \tcode{void}'', +where \cvqual{cv12} is the union of \cvqual{cv1} and \cvqual{cv2}; \item if \tcode{T1} or \tcode{T2} is ``pointer to \tcode{noexcept} function'' and the @@ -352,7 +353,7 @@ A \indextext{literal}% \indextext{constant}% -\grammarterm{literal} +\grammarterm{literal} is a primary expression. Its type depends on its form~(\ref{lex.literal}). A string literal is an lvalue; all other literals are prvalues. @@ -369,7 +370,7 @@ If a declaration declares a member function or member function template of a class \tcode{X}, the expression \tcode{this} is a prvalue of type ``pointer to \grammarterm{cv-qualifier-seq} \tcode{X}'' between the optional -\grammarterm{cv-qualifer-seq} and the end of the \grammarterm{function-definition}, +\grammarterm{cv-qualifier-seq} and the end of the \grammarterm{function-definition}, \grammarterm{member-declarator}, or \grammarterm{declarator}. It shall not appear before the optional \grammarterm{cv-qualifier-seq} and it shall not appear within the declaration of a static member function (although its type and value category @@ -503,12 +504,12 @@ 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; -it is a bit-field if the identifier designates a bit-field~(\ref{dcl.decomp}). +it is a bit-field if the identifier designates a bit-field~(\ref{dcl.struct.bind}). \rSec3[expr.prim.id.qual]{Qualified names} \indextext{operator!scope resolution}% -\indextext{\idxcode{::}|see{scope resolution operator}}% +\indextext{\idxcode{::}|see{operator, scope resolution}}% % \begin{bnf} \nontermdef{qualified-id}\br @@ -540,7 +541,7 @@ or one of its base classes (Clause~\ref{class.derived}), is a \indextext{id!qualified}% \grammarterm{qualified-id};~\ref{class.qual} describes name lookup for -class members that appear in \grammarterm{qualified-ids}. The result is the +class members that appear in \grammarterm{qualified-id}{s}. The result is the member. The type of the result is the type of the member. The result is an lvalue if the member is a static member function or a data member and a prvalue otherwise. @@ -568,7 +569,7 @@ \grammarterm{using-directive}), is a \indextext{id!qualified}% \grammarterm{qualified-id};~\ref{namespace.qual} describes name lookup for -namespace members that appear in \grammarterm{qualified-ids}. The result is +namespace members that appear in \grammarterm{qualified-id}{s}. The result is the member. The type of the result is the type of the member. The result is an lvalue if the member is a function or a variable and a prvalue otherwise. @@ -601,45 +602,6 @@ \terminal{[} lambda-capture\opt{} \terminal{]} \end{bnf} -\begin{bnf} -\nontermdef{lambda-capture}\br - capture-default\br - capture-list\br - capture-default \terminal{,} capture-list -\end{bnf} - -\begin{bnf} -\nontermdef{capture-default}\br - \terminal{\&}\br - \terminal{=} -\end{bnf} - -\begin{bnf} -\nontermdef{capture-list}\br - capture \terminal{...\opt}\br - capture-list \terminal{,} capture \terminal{...\opt} -\end{bnf} - -\begin{bnf} -\nontermdef{capture}\br - simple-capture\br - init-capture -\end{bnf} - -\begin{bnf} -\nontermdef{simple-capture}\br - identifier\br - \terminal{\&} identifier\br - \terminal{this}\br - \terminal{* this} -\end{bnf} - -\begin{bnf} -\nontermdef{init-capture}\br - identifier initializer\br - \terminal{\&} identifier initializer -\end{bnf} - \begin{bnf} \nontermdef{lambda-declarator}\br \terminal{(} parameter-declaration-clause \terminal{)} decl-specifier-seq\opt\br @@ -658,37 +620,6 @@ \end{codeblock} \end{example} -\pnum -In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, -each \grammarterm{decl-specifier} -shall either be \tcode{mutable} or \tcode{constexpr}. -\begin{example} -\begin{codeblock} -auto monoid = [](auto v) { return [=] { return v; }; }; -auto add = [](auto m1) constexpr { - auto ret = m1(); - return [=](auto m2) mutable { - auto m1val = m1(); - auto plus = [=](auto m2val) mutable constexpr - { return m1val += m2val; }; - ret = plus(m2()); - return monoid(ret); - }; -}; -constexpr auto zero = monoid(0); -constexpr auto one = monoid(1); -static_assert(add(one)(zero)() == one()); // OK - -// Since \tcode{two} below is not declared \tcode{constexpr}, an evaluation of its \tcode{constexpr} member function call operator -// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture) -// in a constant expression. -auto two = monoid(2); -assert(two() == 2); // OK, not a constant expression. -static_assert(add(one)(one)() == two()); // ill-formed: \tcode{two()} is not a constant expression -static_assert(add(one)(one)() == monoid(2)()); // OK -\end{codeblock} -\end{example} - \pnum A \grammarterm{lambda-expression} is a prvalue whose result object is called the \defn{closure object}. A @@ -705,17 +636,43 @@ object~(\ref{function.objects}).\end{note} \pnum -The type of the \grammarterm{lambda-expression} (which is also the type of the -closure object) is a unique, unnamed non-union class type ---- called the \defn{closure type} --- +In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, +each \grammarterm{decl-specifier} +shall either be \tcode{mutable} or \tcode{constexpr}. + +\pnum +If a \grammarterm{lambda-expression} does not include a +\grammarterm{lambda-declarator}, it is as if the \grammarterm{lambda-declarator} were +\tcode{()}. +The lambda return type is \tcode{auto}, which is replaced by the +type specified by the +\grammarterm{trailing-return-type} if provided and/or deduced from +\tcode{return} statements as described in~\ref{dcl.spec.auto}. +\begin{example} +\begin{codeblock} +auto x1 = [](int i){ return i; }; // OK: return type is \tcode{int} +auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} +int j; +auto x3 = []()->auto&& { return j; }; // OK: return type is \tcode{int\&} +\end{codeblock} +\end{example} + +\rSec3[expr.prim.lambda.closure]{Closure types}% + +\pnum +The type of a \grammarterm{lambda-expression} (which is also the type of the +closure object) is a unique, unnamed non-union class type, +called the \defn{closure type}, whose properties are described below. -This class type is not an aggregate type~(\ref{dcl.init.aggr}). + +\pnum The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding \grammarterm{lambda-expression}. \begin{note} This determines the set of namespaces and classes associated with the closure type~(\ref{basic.lookup.argdep}). The parameter types of a \grammarterm{lambda-declarator} do not affect these associated namespaces and -classes. \end{note} An implementation may define the closure type differently from what +classes. \end{note} The closure type is not an aggregate type~(\ref{dcl.init.aggr}). +An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing: @@ -733,23 +690,6 @@ An implementation shall not add members of rvalue reference type to the closure type. -\pnum -If a \grammarterm{lambda-expression} does not include a -\grammarterm{lambda-declarator}, it is as if the \grammarterm{lambda-declarator} were -\tcode{()}. -The lambda return type is \tcode{auto}, which is replaced by the -type specified by the -\grammarterm{trailing-return-type} if provided and/or deduced from -\tcode{return} statements as described in~\ref{dcl.spec.auto}. -\begin{example} -\begin{codeblock} -auto x1 = [](int i){ return i; }; // OK: return type is \tcode{int} -auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} -int j; -auto x3 = []()->auto&& { return j; }; // OK: return type is \tcode{int\&} -\end{codeblock} -\end{example} - \pnum The closure type for a non-generic \grammarterm{lambda-expression} has a public inline function call operator~(\ref{over.call}) whose parameters and return type @@ -790,7 +730,9 @@ q(); // OK: outputs \tcode{1a3.14} \end{codeblock} \end{example} -This function call operator or operator template is declared + +\pnum +The function call operator or operator template is declared \tcode{const}~(\ref{class.mfct.non-static}) if and only if the \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not followed by \tcode{mutable}. It is neither virtual nor declared \tcode{volatile}. Any @@ -819,6 +761,34 @@ \end{codeblock} \end{example} +\pnum +\begin{example} +\begin{codeblock} +auto monoid = [](auto v) { return [=] { return v; }; }; +auto add = [](auto m1) constexpr { + auto ret = m1(); + return [=](auto m2) mutable { + auto m1val = m1(); + auto plus = [=](auto m2val) mutable constexpr + { return m1val += m2val; }; + ret = plus(m2()); + return monoid(ret); + }; +}; +constexpr auto zero = monoid(0); +constexpr auto one = monoid(1); +static_assert(add(one)(zero)() == one()); // OK + +// Since \tcode{two} below is not declared \tcode{constexpr}, an evaluation of its \tcode{constexpr} member function call operator +// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture) +// in a constant expression. +auto two = monoid(2); +assert(two() == 2); // OK, not a constant expression. +static_assert(add(one)(one)() == two()); // ill-formed: \tcode{two()} is not a constant expression +static_assert(add(one)(one)() == monoid(2)()); // OK +\end{codeblock} +\end{example} + \pnum The closure type for a non-generic \grammarterm{lambda-expression} with no \grammarterm{lambda-capture} @@ -841,6 +811,8 @@ the pointer to function shall behave as if it were a \grammarterm{decltype-specifier} denoting the return type of the corresponding function call operator template specialization. + +\pnum \begin{note} If the generic lambda has no \grammarterm{trailing-return-type} or the \grammarterm{trailing-return-type} contains a placeholder type, return type @@ -891,6 +863,7 @@ \end{codeblock} \end{example} +\pnum The value returned by any given specialization of this conversion function template is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator @@ -910,6 +883,7 @@ \end{codeblock} \end{example} +\pnum The conversion function or conversion function template is public, constexpr, non-virtual, non-explicit, const, and has a non-throwing exception specification~(\ref{except.spec}). @@ -952,6 +926,70 @@ the \grammarterm{compound-statement} of the \grammarterm{lambda-expression}, with semantics as described in~\ref{dcl.fct.def.general}. +\pnum +The closure type associated with a \grammarterm{lambda-expression} has no +default constructor and a deleted copy assignment operator. It has a +defaulted copy constructor and a defaulted move constructor~(\ref{class.copy}). +\begin{note} These special member functions are implicitly defined as +usual, and might therefore be defined as deleted. \end{note} + +\pnum +The closure type associated with a \grammarterm{lambda-expression} has an +implicitly-declared destructor~(\ref{class.dtor}). + +\pnum +A member of a closure type shall not be +explicitly instantiated~(\ref{temp.explicit}), +explicitly specialized~(\ref{temp.expl.spec}), or +named in a \tcode{friend} declaration~(\ref{class.friend}). + +\rSec3[expr.prim.lambda.capture]{Captures}% + +\begin{bnf} +\nontermdef{lambda-capture}\br + capture-default\br + capture-list\br + capture-default \terminal{,} capture-list +\end{bnf} + +\begin{bnf} +\nontermdef{capture-default}\br + \terminal{\&}\br + \terminal{=} +\end{bnf} + +\begin{bnf} +\nontermdef{capture-list}\br + capture \terminal{...\opt}\br + capture-list \terminal{,} capture \terminal{...\opt} +\end{bnf} + +\begin{bnf} +\nontermdef{capture}\br + simple-capture\br + init-capture +\end{bnf} + +\begin{bnf} +\nontermdef{simple-capture}\br + identifier\br + \terminal{\&} identifier\br + \terminal{this}\br + \terminal{* this} +\end{bnf} + +\begin{bnf} +\nontermdef{init-capture}\br + identifier initializer\br + \terminal{\&} identifier initializer +\end{bnf} + +\pnum +The body of a \grammarterm{lambda-expression} may refer to variables +with automatic storage duration and the \tcode{*this} object (if any) +of enclosing block scopes by capturing those entities, as described +below. + \pnum If a \grammarterm{lambda-capture} includes a \grammarterm{capture-default} that is \tcode{\&}, no identifier in a \grammarterm{simple-capture} of that @@ -1001,6 +1039,20 @@ a variable with automatic storage duration declared in the reaching scope of the local lambda expression. +\pnum +If an \grammarterm{identifier} in a \grammarterm{simple-capture} appears +as the \grammarterm{declarator-id} of a parameter of +the \grammarterm{lambda-declarator}{'s} \grammarterm{parameter-declaration-clause}, +the program is ill-formed. +\begin{example} +\begin{codeblock} +void f() { + int x = 0; + auto g = [x](int x) { return 0; } // error: parameter and \grammarterm{simple-capture} have the same name +} +\end{codeblock} +\end{example} + \pnum An \grammarterm{init-capture} behaves as if it declares and explicitly captures a variable of @@ -1027,6 +1079,8 @@ r += 2; return x+2; }(); // Updates \tcode{::x} to 6, and initializes \tcode{y} to 7. + +auto z = [a = 42](int a) { return 1; } // error: parameter and local variable have the same name \end{codeblock} \end{example} @@ -1179,7 +1233,16 @@ 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~(\ref{expr.cast}) to the type of \tcode{this}. \begin{note} The cast ensures that the -transformed expression is a prvalue. \end{note} \begin{example} +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} +\begin{example} \begin{codeblock} void f(const int*); void g() { @@ -1190,6 +1253,12 @@ // 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} @@ -1260,23 +1329,6 @@ \end{codeblock} \end{example} -\pnum -The closure type associated with a \grammarterm{lambda-expression} has no -default constructor and a deleted copy assignment operator. It has a -defaulted copy constructor and a defaulted move constructor~(\ref{class.copy}). -\begin{note} These special member functions are implicitly defined as -usual, and might therefore be defined as deleted. \end{note} - -\pnum -The closure type associated with a \grammarterm{lambda-expression} has an -implicitly-declared destructor~(\ref{class.dtor}). - -\pnum -A member of a closure type shall not be -explicitly instantiated~(\ref{temp.explicit}), -explicitly specialized~(\ref{temp.expl.spec}), or -named in a \tcode{friend} declaration~(\ref{class.friend}). - \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 @@ -1289,7 +1341,7 @@ \end{note} \pnum -\begin{note} If an entity is implicitly or explicitly captured by reference, +\begin{note} If a non-reference entity is implicitly or explicitly captured by reference, invoking the function call operator of the corresponding \grammarterm{lambda-expression} after the lifetime of the entity has ended is likely to result in undefined behavior. \end{note} @@ -1864,7 +1916,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} \grammarterm{ref-qualifier}\opt{} returning \tcode{T}'', then \tcode{E1.E2} is a prvalue. The expression designates a non-static member function. The expression can be used only as the left-hand operand of a member function call~(\ref{class.mfct}). @@ -2186,7 +2238,7 @@ ``\cvqual{cv1} \tcode{B}'' can be cast to type ``rvalue reference to \cvqual{cv2} \tcode{D}'' with the same constraints as for an lvalue of type ``\cvqual{cv1} \tcode{B}''. If the object -of type ``\cvqual{cv1} \tcode{B}'' is actually a subobject of an object +of type ``\cvqual{cv1} \tcode{B}'' is actually a base class subobject of an object of type \tcode{D}, the result refers to the enclosing object of type \tcode{D}. Otherwise, the behavior is undefined. \begin{example} @@ -2221,7 +2273,7 @@ from \tcode{e} to \tcode{T}, or if overload resolution for a direct-initialization~(\ref{dcl.init}) of an object or reference of type \tcode{T} from \tcode{e} -would find at least one viable function~(\ref{over.match.viable}). +would find at least one viable function~(\ref{over.match.viable}). If \tcode{T} is a reference type, the effect is the same as performing the declaration and initialization \begin{codeblock} @@ -2319,7 +2371,7 @@ If \tcode{B} is a virtual base class of \tcode{D} or a base class of a virtual base class of \tcode{D}, or if no valid standard conversion from ``pointer to \tcode{D}'' -to ``pointer to \tcode{B}'' exists~(\ref{conv.ptr}), the program is ill-formed. +to ``pointer to \tcode{B}'' exists~(\ref{conv.ptr}), the program is ill-formed. The null pointer value~(\ref{conv.ptr}) is converted to the null pointer value of the destination type. If the prvalue of type ``pointer to \cvqual{cv1} \tcode{B}'' points to a \tcode{B} that is @@ -2366,7 +2418,7 @@ and there is an object \placeholder{b} of type \tcode{T} (ignoring cv-qualification) that is pointer-interconvertible~(\ref{basic.compound}) with \placeholder{a}, the result is a pointer to \placeholder{b}. -Otherwise, the pointer value is unchanged by the conversion. +Otherwise, the pointer value is unchanged by the conversion. \begin{example} \begin{codeblock} @@ -2876,7 +2928,7 @@ \grammarterm{type-id}. \indextext{type!incomplete}% The \tcode{sizeof} operator shall not be applied to an expression that -has function or incomplete type, +has function or incomplete type, to the parenthesized name of such types, or to a glvalue that designates a bit-field. \tcode{sizeof(char)}, \tcode{sizeof(signed char)} and @@ -3029,28 +3081,26 @@ If a placeholder type~(\ref{dcl.spec.auto}) appears in the \grammarterm{type-specifier-seq} of a \grammarterm{new-type-id} or \grammarterm{type-id} of a \grammarterm{new-expression}, -the \grammarterm{new-expression} shall contain a -\grammarterm{new-initializer} of the form - -\begin{ncsimplebnf} -\terminal{(} assignment-expression \terminal{)} -\end{ncsimplebnf} - -The allocated type is deduced from the \grammarterm{new-initializer} as -follows: Let \tcode{e} be the \grammarterm{assignment-expression} in the \grammarterm{new-initializer} and +the allocated type is deduced as follows: +Let +\placeholder{init} be the \grammarterm{new-initializer}, if any, +and \tcode{T} be the \grammarterm{new-type-id} or \grammarterm{type-id} of the \grammarterm{new-expression}, then the allocated type is the type deduced for the variable \tcode{x} in the invented declaration~(\ref{dcl.spec.auto}): \begin{codeblock} -T x(e); +T x @\textrm{\placeholder{init}}@ ; \end{codeblock} \begin{example} \begin{codeblock} new auto(1); // allocated type is \tcode{int} auto x = new auto('a'); // allocated type is \tcode{char}, \tcode{x} is of type \tcode{char*} + +template struct A { A(T, T); }; +auto y = new A{1, 2}; // allocated type is \tcode{A} \end{codeblock} \end{example} @@ -3117,11 +3167,11 @@ \pnum Every \grammarterm{constant-expression} in a \grammarterm{noptr-new-declarator} shall be a converted constant -expression~(\ref{expr.const}) of type \tcode{std\colcol{}size_t} and +expression~(\ref{expr.const}) of type \tcode{std::size_t} and shall evaluate to a strictly positive value. \indextext{\idxcode{new}}% The \grammarterm{expression} in a \grammarterm{noptr-new-declarator} is -implicitly converted to \tcode{std\colcol{}size_t}. +implicitly converted to \tcode{std::size_t}. \begin{example} Given the definition \tcode{int n = 42}, \tcode{new float[n][5]} is well-formed (because \tcode{n} is the @@ -3279,10 +3329,11 @@ allocation has not been extended, the \grammarterm{new-expression} passes the amount of space requested to the allocation function as the first argument of type -\tcode{std\colcol{}size_t}. That argument shall be no less than the size +\tcode{std::size_t}. That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array. For arrays of -\tcode{char} and \tcode{unsigned char}, the difference between the +\tcode{char}, \tcode{unsigned char}, and \tcode{std::byte}, +the difference between the result of the \grammarterm{new-expression} and the address returned by the allocation function shall be an integral multiple of the strictest fundamental @@ -3469,7 +3520,7 @@ will be called; otherwise, no deallocation function will be called. If the lookup finds a usual deallocation function -with a parameter of type \tcode{std\colcol{}size_t}~(\ref{basic.stc.dynamic.deallocation}) +with a parameter of type \tcode{std::size_t}~(\ref{basic.stc.dynamic.deallocation}) and that function, considered as a placement deallocation function, would have been selected as a match for the allocation function, the program is @@ -3479,16 +3530,16 @@ \begin{example} \begin{codeblock} -struct S { +struct S { // Placement allocation function: - static void* operator new(std::size_t, std::size_t); + static void* operator new(std::size_t, std::size_t); // Usual (non-placement) deallocation function: - static void operator delete(void*, std::size_t); -}; + static void operator delete(void*, std::size_t); +}; -S* p = new (0) S; // ill-formed: non-placement deallocation function matches - // placement allocation function +S* p = new (0) S; // ill-formed: non-placement deallocation function matches + // placement allocation function \end{codeblock} \end{example} @@ -3639,11 +3690,10 @@ \pnum \begin{note} An implementation provides default definitions of the global -deallocation functions \tcode{operator delete()} for +deallocation functions \tcode{operator delete} for non-arrays~(\ref{new.delete.single}) and -\indextext{operator |see{\tcode{delete}}}% \indextext{\idxcode{operator delete}}% -\tcode{operator delete[]()} for arrays~(\ref{new.delete.array}). A \Cpp +\tcode{operator delete[]} for arrays~(\ref{new.delete.array}). A \Cpp program can provide alternative definitions of these functions~(\ref{replacement.functions}), and/or class-specific versions~(\ref{class.free}). @@ -3663,7 +3713,7 @@ \begin{itemize} \item If the type has new-extended alignment, -a function with a parameter of type \tcode{std\colcol{}align_val_t} is preferred; +a function with a parameter of type \tcode{std::align_val_t} is preferred; otherwise a function without such a parameter is preferred. If exactly one preferred function is found, that function is selected and the selection process terminates. @@ -3671,35 +3721,46 @@ all non-preferred functions are eliminated from further consideration. \item If the deallocation functions have class scope, -the one without a parameter of type \tcode{std\colcol{}size_t} is selected. +the one without a parameter of type \tcode{std::size_t} is selected. \item If the type is complete and if, for the second alternative (delete array) only, the operand is a pointer to a class type with a non-trivial destructor or a (possibly multi-dimensional) array thereof, -the function with a parameter of type \tcode{std\colcol{}size_t} is selected. +the function with a parameter of type \tcode{std::size_t} is selected. \item Otherwise, it is unspecified -whether a deallocation function with a parameter of type \tcode{std\colcol{}size_t} +whether a deallocation function with a parameter of type \tcode{std::size_t} is selected. \end{itemize} \pnum When a \grammarterm{delete-expression} is executed, the selected deallocation function shall be called with -the address of the block of storage to be reclaimed as its first argument. +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~(\ref{expr.new}) in the \term{delete array} case, +as its first argument. If a deallocation function -with a parameter of type \tcode{std\colcol{}align_val_t} +with a parameter of type \tcode{std::align_val_t} is used, the alignment of the type of the object to be deleted is passed as the corresponding argument. If a deallocation function -with a parameter of type \tcode{std\colcol{}size_t} -is used, -the size of the block +with a parameter of type \tcode{std::size_t} is used, +the size +of the most-derived type, or +of the array plus allocation overhead, respectively, is passed as the corresponding argument.% \footnote{If the static type of the object to be deleted is complete and is different from the dynamic type, and the destructor is not virtual, the size might be incorrect, but that case is already undefined, as stated above.} +\begin{note} +If this results in a call to a usual deallocation function, and either +the first argument was not the result of +a prior call to a usual allocation function or +the second argument was not the corresponding argument in said call, +the behavior is undefined~(\ref{new.delete.single}, \ref{new.delete.array}). +\end{note} \pnum Access and ambiguity control are done for both the deallocation function @@ -3756,7 +3817,7 @@ is an rvalue reference to object type; otherwise the result is a prvalue. \begin{note} If \tcode{T} is a non-class type that is cv-qualified, the -\grammarterm{cv-qualifiers} are discarded when determining the type of the +\grammarterm{cv-qualifier}{s} are discarded when determining the type of the resulting prvalue; see Clause~\ref{expr}. \end{note} @@ -3942,7 +4003,7 @@ operand is an lvalue and an xvalue otherwise. The result of a \tcode{.*} expression whose second operand is a pointer to a member function is a prvalue. If the second operand is the null -pointer to member value~(\ref{conv.mem}), the behavior is undefined. +member pointer value~(\ref{conv.mem}), the behavior is undefined. \rSec1[expr.mul]{Multiplicative operators}% \indextext{expression!multiplicative operators}% @@ -4042,12 +4103,12 @@ When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression \tcode{P} points to element $\mathtt{x[}i\mathtt{]}$ -of an array object \tcode{x} with $n$ elements% +of an array object \tcode{x} with $n$ elements,% \footnote{An object that is not an array element is considered to belong to a single-element array for this purpose; see~\ref{expr.unary.op}. A pointer past the last element of an array \tcode{x} of $n$ elements is considered to be equivalent to a pointer to a hypothetical element -$\mathtt{x[}n\mathtt{]}$ for this purpose; see~\ref{basic.compound}.}, +$\mathtt{x[}n\mathtt{]}$ for this purpose; see~\ref{basic.compound}.} the expressions \tcode{P + J} and \tcode{J + P} (where \tcode{J} has the value $j$) point to the (possibly-hypothetical) element @@ -4105,7 +4166,8 @@ \pnum \indextext{expression!left-shift-operator}% \indextext{expression!right-shift-operator}% -\indextext{shift operator|see{operator, left shift; operator, right shift}}% +\indextext{shift operator!left|see{operator, left shift}}% +\indextext{shift operator!right|see{operator, right shift}}% \indextext{right shift operator|see{operator, right shift}}% \indextext{left shift operator|see{operator, left shift}}% The shift operators \tcode{<<} and \tcode{>>} group left-to-right. @@ -4267,9 +4329,9 @@ \item If one pointer represents the address of a complete object, and another pointer represents the address one past the last element of a different -complete object \footnote{An object that is not an array element is +complete object,\footnote{An object that is not an array element is considered to belong to a single-element array for this purpose; -see~\ref{expr.unary.op}.}, the result of the comparison is unspecified. +see~\ref{expr.unary.op}.} the result of the comparison is unspecified. \item Otherwise, if the pointers are both null, both point to the same \indextext{address}% @@ -4540,7 +4602,7 @@ of the operand expression \tcode{E2} as follows: \begin{itemize} -\item If \tcode{E2} is an lvalue, the target type is +\item If \tcode{E2} is an lvalue, the target type is ``lvalue reference to \tcode{T2}'', subject to the constraint that in the conversion the reference must bind directly~(\ref{dcl.init.ref}) to an lvalue. @@ -4557,7 +4619,7 @@ (ignoring cv-qualification), or one is a base class of the other, and \tcode{T2} is at least as cv-qualified as \tcode{T1}, the target type is \tcode{T2}, - + \item otherwise, the target type is the type that \tcode{E2} would have after applying the lvalue-to-rvalue~(\ref{conv.lval}), @@ -4568,7 +4630,7 @@ \end{itemize} Using this process, it is determined whether an implicit conversion -sequence can be formed from the second operand +sequence can be formed from the second operand to the target type determined for the third operand, and vice versa. If both sequences can be formed, or one can be formed but it is the ambiguous conversion sequence, the program is ill-formed. @@ -4649,7 +4711,7 @@ \pnum Evaluating a \grammarterm{throw-expression} with an operand throws an exception~(\ref{except.throw}); the type of the exception object is determined by removing -any top-level \grammarterm{cv-qualifiers} from the static type of the +any top-level \grammarterm{cv-qualifier}{s} from the static type of the operand and adjusting the type from ``array of \tcode{T}'' or function type \tcode{T} to ``pointer to \tcode{T}''. @@ -4683,7 +4745,7 @@ evaluating a \grammarterm{throw-expression} with no operand calls -\tcode{std\colcol{}terminate()}~(\ref{except.terminate}). +\tcode{std::\brk{}terminate()}~(\ref{except.terminate}). \rSec1[expr.ass]{Assignment and compound assignment operators}% \indextext{expression!assignment and compound assignment} @@ -4861,7 +4923,7 @@ semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements, assuming that copy elision is performed, -are called +are called \indexdefn{expression!constant}% \defnx{constant expressions}{constant expression}. \begin{note} Constant expressions can be evaluated during translation.\end{note} @@ -4872,14 +4934,14 @@ \end{bnf} \pnum -A \grammarterm{conditional-expression} \tcode{e} is a +An expression \tcode{e} is a \defnx{core constant expression}{expression!core constant} unless the evaluation of \tcode{e}, following the rules of the abstract machine~(\ref{intro.execution}), would evaluate one of the following expressions: \begin{itemize} \item -\tcode{this}~(\ref{expr.prim.this}), except in a \tcode{constexpr} +\tcode{this}~(\ref{expr.prim.this}), except in a constexpr function or a constexpr constructor that is being evaluated as part of \tcode{e}; @@ -4943,6 +5005,12 @@ that is applied to a glvalue that refers to a non-active member of a union or a subobject thereof; +\item +an invocation of an implicitly-defined copy/move constructor or +copy/move assignment operator +for a union whose active member (if any) is mutable, +unless the lifetime of the union object began within the evaluation of \tcode{e}; + \item an assignment expression~(\ref{expr.ass}) or invocation of an assignment operator~(\ref{class.copy}) @@ -4982,7 +5050,7 @@ If the odr-use occurs in an invocation of a function call operator of a closure type, it no longer refers to \tcode{this} or to an enclosing automatic variable -due to the transformation~(\ref{expr.prim.lambda}) +due to the transformation~(\ref{expr.prim.lambda.capture}) of the \grammarterm{id-expression} into an access of the corresponding data member. \begin{example} @@ -5119,7 +5187,7 @@ as enumerator initializers if the underlying type is fixed~(\ref{dcl.enum}), as array bounds~(\ref{dcl.array}), and as non-type template -arguments~(\ref{temp.arg}). +arguments~(\ref{temp.arg}). \end{note} \indextext{contextually converted constant expression of type \tcode{bool}|see{conversion, contextual}}% \indextext{conversion!contextual to constant expression of type \tcode{bool}}% @@ -5180,23 +5248,23 @@ \end{example} \end{note} \pnum -If an expression of literal class type is used in a context where an +If an expression of literal class type is used in a context where an integral constant expression is required, then that expression is contextually implicitly converted (Clause~\ref{conv}) to an integral or unscoped -enumeration type +enumeration type and the selected conversion function shall be \tcode{constexpr}. \begin{example} \begin{codeblock} -struct A { - constexpr A(int i) : val(i) { } +struct A { + constexpr A(int i) : val(i) { } constexpr operator int() const { return val; } constexpr operator long() const { return 43; } -private: - int val; -}; -template struct X { }; -constexpr A a = 42; +private: + int val; +}; +template struct X { }; +constexpr A a = 42; X x; // OK: unique conversion to \tcode{int} -int ary[a]; // error: ambiguous conversion +int ary[a]; // error: ambiguous conversion \end{codeblock} \end{example}% \indextext{expression|)} diff --git a/source/future.tex b/source/future.tex index 7119aef6dc..4af3d13879 100644 --- a/source/future.tex +++ b/source/future.tex @@ -48,10 +48,86 @@ \pnum The \grammarterm{noexcept-specifier} \tcode{throw()} is deprecated. +\rSec1[depr.cpp.headers]{\Cpp standard library headers} + +\pnum +For compatibility with prior \Cpp International Standards, +the \Cpp standard library provides headers +\tcode{}~(\ref{depr.ccomplex.syn}), +\tcode{}~(\ref{depr.cstdalign.syn}), +\tcode{}~(\ref{depr.cstdbool.syn}), +and \tcode{}~(\ref{depr.ctgmath.syn}). +The use of these headers is deprecated. + +\rSec2[depr.ccomplex.syn]{Header \tcode{} synopsis} +\indexlibrary{\idxhdr{ccomplex}}% + +\begin{codeblock} +#include +\end{codeblock} + +\pnum +The header \tcode{} +behaves as if it simply includes the header +\tcode{}~(\ref{complex.syn}). + +\rSec2[depr.cstdalign.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxcode{__alignas_is_defined}}% +\indexlibrary{\idxhdr{cstdalign}}% +\begin{codeblock} +#define @\xname{alignas_is_defined}@ 1 +\end{codeblock} + +\pnum +\indexlibrary{\idxhdr{cstdalign}}% +\indexlibrary{\idxhdr{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 +define a macro named \tcode{alignas}. + +\xref ISO C~7.15. + +\rSec2[depr.cstdbool.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxhdr{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}}% +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 +define macros named \tcode{bool}, \tcode{true}, or \tcode{false}. + +\xref ISO C~7.18. + +\rSec2[depr.ctgmath.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxhdr{ctgmath}}% +\begin{codeblock} +#include +#include +\end{codeblock} + +\pnum +The header \tcode{} simply includes the headers +\tcode{}~(\ref{complex.syn}) +and \tcode{}~(\ref{cmath.syn}). + +\pnum +\begin{note} The overloads provided in C by type-generic macros are already +provided in \tcode{} and \tcode{} by ``sufficient'' additional +overloads.\end{note} + \rSec1[depr.c.headers]{C standard library headers} \pnum -For compatibility with the +For compatibility with the \indextext{library!C standard}% C standard library, the \Cpp standard library provides the \defnx{C headers}{headers!C library} shown in Table~\ref{tab:future.c.headers}. @@ -94,16 +170,9 @@ \end{floattable} -\pnum -The use of any of the \Cpp headers -\tcode{}, -\tcode{}, -\tcode{}, -or \tcode{} -is deprecated. - \pnum The header \tcode{} behaves as if it simply includes the header \tcode{}. +The header \tcode{} behaves as if it simply includes the header \tcode{}. \pnum Every other C header, each of @@ -115,7 +184,9 @@ \tcode{c\textit{name}} header is placed within the global namespace scope, -except for the functions described in \ref{sf.cmath}. +except for the functions described in \ref{sf.cmath}, +the declaration of \tcode{std::byte}~(\ref{cstddef.syn}), and +the functions and function templates described in \ref{support.types.byteops}. It is unspecified whether these names are first declared or defined within namespace scope~(\ref{basic.scope.namespace}) of the namespace \tcode{std} and are then injected into the global namespace scope by @@ -1472,8 +1543,7 @@ only if the type \tcode{T} is any of the following: \begin{itemize} \item a function type or a pointer to function type taking one argument of type \tcode{T1} -% FIXME: Should this be R T0::f() ? -\item a pointer to member function \tcode{R T0::f} \cv{} (where \cv{} represents the member function's cv-qualifiers); the type \tcode{T1} is \cv{}~\tcode{T0*} +\item a pointer to member function \tcode{R T0::f()} \cv{} (where \cv{} represents the member function's cv-qualifiers); the type \tcode{T1} is \cv{}~\tcode{T0*} \item a class type where the \grammarterm{qualified-id} \tcode{T::argument_type} is valid and denotes a type~(\ref{temp.deduct}); the type \tcode{T1} is \tcode{T::argument_type}. @@ -2015,18 +2085,35 @@ template struct is_literal_type; 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; } \end{codeblock} \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 -\effects -\tcode{is_literal_type} has a base-characteristic of \tcode{true_type} if -\tcode{T} is a literal type~(\ref{basic.types}), and a base-characteristic of +\tcode{is_literal_type} is a \tcode{UnaryTypeTrait}~(\ref{meta.rqmts}) +with a base characteristic of \tcode{true_type} +if \tcode{T} is a literal type~(\ref{basic.types}), and \tcode{false_type} otherwise. +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. +If \tcode{type} is defined, it names the same type as \tcode{invoke_result_t}. + +\pnum +The behavior of a program that adds specializations for +\tcode{is_literal_type} or \tcode{is_literal_type_v} is undefined. \rSec1[depr.iterator.primitives]{Deprecated iterator primitives} @@ -2063,7 +2150,7 @@ \begin{note} If the new iterator type is a class template, then these aliases will not be visible from within the iterator class's template definition, but only to callers of that class.\end{note} - + \pnum \begin{example} If a \Cpp program wants to define a bidirectional iterator for some data @@ -2102,3 +2189,524 @@ \begin{itemdescr} \pnum\returns \tcode{use_count() == 1}. \end{itemdescr} + +\rSec1[depr.locale.stdcvt]{Deprecated standard code conversion facets} + +\pnum +\indextext{\idxhdr{codecvt}}% +\indexlibrary{\idxhdr{codecvt}}% +The header \tcode{} provides code conversion facets for various character encodings. + +\rSec2[depr.codecvt.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxcode{codecvt_mode}}% +\indexlibrary{\idxcode{codecvt_utf8}}% +\indexlibrary{\idxcode{codecvt_utf16}}% +\indexlibrary{\idxcode{codecvt_utf8_utf16}}% +\begin{codeblock} +namespace std { + enum codecvt_mode { + consume_header = 4, + generate_header = 2, + little_endian = 1 + }; + + template + class codecvt_utf8 : public codecvt { + public: + explicit codecvt_utf8(size_t refs = 0); + ~codecvt_utf8(); + }; + + template + class codecvt_utf16 : public codecvt { + public: + explicit codecvt_utf16(size_t refs = 0); + ~codecvt_utf16(); + }; + + template + class codecvt_utf8_utf16 : public codecvt { + public: + explicit codecvt_utf8_utf16(size_t refs = 0); + ~codecvt_utf8_utf16(); + }; +} +\end{codeblock} + +\rSec2[depr.locale.stdcvt.req]{Requirements} + +\pnum +For each of the three code conversion facets \tcode{codecvt_utf8}, +\tcode{codecvt_utf16}, and \tcode{codecvt_utf8_utf16}: +\begin{itemize} +\item + \tcode{Elem} is the wide-character type, such as + \tcode{wchar_t}, \tcode{char16_t}, or \tcode{char32_t}. +\item + \tcode{Maxcode} is the largest wide-character code that the facet + will read or write without reporting a conversion error. +\item + If \tcode{(Mode \& consume_header)}, the facet shall consume an + initial header sequence, if present, when reading a multibyte sequence + to determine the endianness of the subsequent multibyte sequence to be read. +\item + If \tcode{(Mode \& generate_header)}, the facet shall generate an + initial header sequence when writing a multibyte sequence to advertise + the endianness of the subsequent multibyte sequence to be written. +\item + If \tcode{(Mode \& little_endian)}, the facet shall generate a + multibyte sequence in little-endian order, + as opposed to the default big-endian order. +\end{itemize} + +\pnum +For the facet \tcode{codecvt_utf8}\indexlibrary{\idxcode{codecvt_utf8}}: +\begin{itemize} +\item + The facet shall convert between UTF-8 multibyte sequences + and UCS2 or UCS4 (depending on the size of \tcode{Elem}) + within the program. +\item + Endianness shall not affect how multibyte sequences are read or written. +\item + The multibyte sequences may be written as either a text or a binary file. +\end{itemize} + +\pnum +For the facet \tcode{codecvt_utf16}\indexlibrary{\idxcode{codecvt_utf16}}: +\begin{itemize} +\item + The facet shall convert between UTF-16 multibyte sequences + and UCS2 or UCS4 (depending on the size of \tcode{Elem}) + within the program. +\item + Multibyte sequences shall be read or written + according to the \tcode{Mode} flag, as set out above. +\item + The multibyte sequences may be written only as a binary file. + Attempting to write to a text file produces undefined behavior. +\end{itemize} + +\pnum +For the facet \tcode{codecvt_utf8_utf16}\indexlibrary{\idxcode{codecvt_utf8_utf16}}: +\begin{itemize} +\item + The facet shall convert between UTF-8 multibyte sequences + and UTF-16 (one or two 16-bit codes) within the program. +\item + Endianness shall not affect how multibyte sequences are read or written. +\item + The multibyte sequences may be written as either a text or a binary file. +\end{itemize} + +\xref ISO/IEC 10646-1:1993. + +\rSec1[depr.conversions]{Deprecated convenience conversion interfaces} + +\pnum +The header \tcode{} has the following additions: + +\begin{codeblock} +namespace std { + template , + class Byte_alloc = allocator> + class wstring_convert; + + template > + class wbuffer_convert; +} +\end{codeblock} + +\rSec2[depr.conversions.string]{Class template \tcode{wstring_convert}} + +\pnum +Class template \tcode{wstring_convert} performs conversions between a wide +string and a byte string. It lets you specify a code conversion facet +(like class template \tcode{codecvt}) to perform the conversions, without +affecting any streams or locales. \begin{example} If you want to use the code +conversion facet \tcode{codecvt_utf8} to output to \tcode{cout} a UTF-8 +multibyte sequence corresponding to a wide string, but you don't want to +alter the locale for \tcode{cout}, you can write something like: +\begin{codeblock} +wstring_convert> myconv; +std::string mbstring = myconv.to_bytes(L"Hello\n"); +std::cout << mbstring; +\end{codeblock} +\end{example} + +\indexlibrary{\idxcode{wstring_convert}}% +\begin{codeblock} +namespace std { + template , + class Byte_alloc = allocator> + class wstring_convert { + public: + using byte_string = basic_string, Byte_alloc>; + using wide_string = basic_string, Wide_alloc>; + using state_type = typename Codecvt::state_type; + using int_type = typename wide_string::traits_type::int_type; + + explicit wstring_convert(Codecvt* pcvt = new Codecvt); + wstring_convert(Codecvt* pcvt, state_type state); + explicit wstring_convert(const byte_string& byte_err, + const wide_string& wide_err = wide_string()); + ~wstring_convert(); + + wstring_convert(const wstring_convert&) = delete; + wstring_convert& operator=(const wstring_convert&) = delete; + + wide_string from_bytes(char byte); + wide_string from_bytes(const char* ptr); + wide_string from_bytes(const byte_string& str); + wide_string from_bytes(const char* first, const char* last); + + byte_string to_bytes(Elem wchar); + byte_string to_bytes(const Elem* wptr); + byte_string to_bytes(const wide_string& wstr); + byte_string to_bytes(const Elem* first, const Elem* last); + + size_t converted() const noexcept; + state_type state() const; + + private: + byte_string byte_err_string; // \expos + wide_string wide_err_string; // \expos + Codecvt* cvtptr; // \expos + state_type cvtstate; // \expos + size_t cvtcount; // \expos + }; +} +\end{codeblock} + +\pnum +The class template describes an object that controls conversions between wide +string objects of class \tcode{basic_string, +Wide_alloc>} and byte string objects of class \tcode{basic_string, Byte_alloc>}. The class template defines the types +\tcode{wide_string} and \tcode{byte_string} as synonyms for these two types. +Conversion between a sequence of \tcode{Elem} values (stored in a +\tcode{wide_string} object) and multibyte sequences (stored in a +\tcode{byte_string} object) is performed by an object of class +\tcode{Codecvt}, which meets the +requirements of the standard code-conversion facet \tcode{codecvt}. + +\pnum +An object of this class template stores: + +\begin{itemize} +\item \tcode{byte_err_string} --- a byte string to display on errors +\item \tcode{wide_err_string} --- a wide string to display on errors +\item \tcode{cvtptr} --- a pointer to the allocated conversion object +(which is freed when the \tcode{wstring_convert} object is destroyed) +\item \tcode{cvtstate} --- a conversion state object +\item \tcode{cvtcount} --- a conversion count +\end{itemize} + +\indexlibrarymember{byte_string}{wstring_convert}% +\begin{itemdecl} +using byte_string = basic_string, Byte_alloc>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type shall be a synonym for \tcode{basic_string, Byte_alloc>}. +\end{itemdescr} + +\indexlibrarymember{converted}{wstring_convert}% +\begin{itemdecl} +size_t converted() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{cvtcount}. +\end{itemdescr} + +\indexlibrarymember{from_bytes}{wstring_convert}% +\begin{itemdecl} +wide_string from_bytes(char byte); +wide_string from_bytes(const char* ptr); +wide_string from_bytes(const byte_string& str); +wide_string from_bytes(const char* first, const char* last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +The first member function shall convert the single-element sequence \tcode{byte} to a +wide string. The second member function shall convert the null-terminated +sequence beginning at \tcode{ptr} to a wide string. The third member function +shall convert the sequence stored in \tcode{str} to a wide string. The fourth member +function shall convert the sequence defined by the range \range{first}{last} to a +wide string. + +\pnum +In all cases: + +\begin{itemize} +\item If the \tcode{cvtstate} object was not constructed with an explicit value, it +shall be set to its default value (the initial conversion state) before the +conversion begins. Otherwise it shall be left unchanged. + +\item The number of input elements successfully converted shall be stored in \tcode{cvtcount}. +\end{itemize} + +\pnum +\returns +If no conversion error occurs, the member function shall return the converted wide string. +Otherwise, if the object was constructed with a wide-error string, the +member function shall return the wide-error string. +Otherwise, the member function throws an object of class \tcode{range_error}. +\end{itemdescr} + +\indexlibrarymember{int_type}{wstring_convert}% +\begin{itemdecl} +using int_type = typename wide_string::traits_type::int_type; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type shall be a synonym for \tcode{wide_string::traits_type::int_type}. +\end{itemdescr} + +\indexlibrarymember{state}{wstring_convert}% +\begin{itemdecl} +state_type state() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +returns \tcode{cvtstate}. +\end{itemdescr} + +\indexlibrarymember{state_type}{wstring_convert}% +\begin{itemdecl} +using state_type = typename Codecvt::state_type; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type shall be a synonym for \tcode{Codecvt::state_type}. +\end{itemdescr} + +\indexlibrarymember{to_bytes}{wstring_convert}% +\begin{itemdecl} +byte_string to_bytes(Elem wchar); +byte_string to_bytes(const Elem* wptr); +byte_string to_bytes(const wide_string& wstr); +byte_string to_bytes(const Elem* first, const Elem* last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +The first member function shall convert the single-element sequence \tcode{wchar} to a byte string. +The second member function shall convert the null-terminated sequence beginning at \tcode{wptr} to +a byte string. The third member function shall convert the sequence stored in \tcode{wstr} to a +byte string. The fourth member function shall convert the sequence defined by the +range \range{first}{last} to a byte string. + +\pnum +In all cases: + +\begin{itemize} +\item If the \tcode{cvtstate} object was not constructed with an explicit value, it +shall be +set to its default value (the initial conversion state) before the +conversion begins. Otherwise it shall be left unchanged. +\item The number of input elements successfully converted shall be stored +in \tcode{cvtcount}. +\end{itemize} + +\pnum +\returns +If no conversion error occurs, the member function shall return the converted byte string. +Otherwise, if the object was constructed with a byte-error string, the +member function shall return the byte-error string. +Otherwise, the member function shall throw an object of class \tcode{range_error}. +\end{itemdescr} + +\indexlibrarymember{wide_string}{wstring_convert}% +\begin{itemdecl} +using wide_string = basic_string, Wide_alloc>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type shall be a synonym for \tcode{basic_string, Wide_alloc>}. +\end{itemdescr} + +\indexlibrary{\idxcode{wstring_convert}!constructor}% +\begin{itemdecl} +explicit wstring_convert(Codecvt* pcvt = new Codecvt); +wstring_convert(Codecvt* pcvt, state_type state); +explicit wstring_convert(const byte_string& byte_err, + const wide_string& wide_err = wide_string()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +For the first and second constructors, \tcode{pcvt != nullptr}. + +\pnum +\effects +The first constructor shall store \tcode{pcvt} in \tcode{cvtptr} and +default values in \tcode{cvtstate}, \tcode{byte_err_string}, and +\tcode{wide_err_string}. +The second constructor shall store \tcode{pcvt} in \tcode{cvtptr}, +\tcode{state} in \tcode{cvtstate}, and default values in +\tcode{byte_err_string} and \tcode{wide_err_string}; moreover the +stored state shall be retained between calls to \tcode{from_bytes} and +\tcode{to_bytes}. +The third constructor shall store \tcode{new Codecvt} in \tcode{cvtptr}, +\tcode{state_type()} in \tcode{cvtstate}, \tcode{byte_err} +in \tcode{byte_err_string}, and \tcode{wide_err} in +\tcode{wide_err_string}. +\end{itemdescr} + +\indexlibrary{\idxcode{wstring_convert}!destructor}% +\begin{itemdecl} +~wstring_convert(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects The destructor shall delete \tcode{cvtptr}. +\end{itemdescr} + +\rSec2[depr.conversions.buffer]{Class template \tcode{wbuffer_convert}} + +\pnum +Class template \tcode{wbuffer_convert} looks like a wide stream buffer, but +performs all its I/O through an underlying byte stream buffer that you +specify when you construct it. Like class template \tcode{wstring_convert}, it +lets you specify a code conversion facet to perform the conversions, +without affecting any streams or locales. + +\indexlibrary{\idxcode{wbuffer_convert}}% +\begin{codeblock} +namespace std { + template > + class wbuffer_convert : public basic_streambuf { + public: + using state_type = typename Codecvt::state_type; + + explicit wbuffer_convert(streambuf* bytebuf = 0, + Codecvt* pcvt = new Codecvt, + state_type state = state_type()); + + ~wbuffer_convert(); + + wbuffer_convert(const wbuffer_convert&) = delete; + wbuffer_convert& operator=(const wbuffer_convert&) = delete; + + streambuf* rdbuf() const; + streambuf* rdbuf(streambuf* bytebuf); + + state_type state() const; + + private: + streambuf* bufptr; // \expos + Codecvt* cvtptr; // \expos + state_type cvtstate; // \expos + }; +} +\end{codeblock} + +\pnum +The class template describes a stream buffer that controls the +transmission of elements of type \tcode{Elem}, whose character traits are +described by the class \tcode{Tr}, to and from a byte stream buffer of type +\tcode{streambuf}. Conversion between a sequence of \tcode{Elem} values and +multibyte sequences is performed by an object of class +\tcode{Codecvt}, which shall meet the requirements +of the standard code-conversion facet \tcode{codecvt}. + +\pnum +An object of this class template stores: + +\begin{itemize} +\item \tcode{bufptr} --- a pointer to its underlying byte stream buffer +\item \tcode{cvtptr} --- a pointer to the allocated conversion object +(which is freed when the \tcode{wbuffer_convert} object is destroyed) +\item \tcode{cvtstate} --- a conversion state object +\end{itemize} + +\indexlibrarymember{state}{wbuffer_convert}% +\begin{itemdecl} +state_type state() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{cvtstate}. +\end{itemdescr} + +\indexlibrarymember{rdbuf}{wbuffer_convert}% +\begin{itemdecl} +streambuf* rdbuf() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{bufptr}. +\end{itemdescr} + +\indexlibrarymember{rdbuf}{wbuffer_convert}% +\begin{itemdecl} +streambuf* rdbuf(streambuf* bytebuf); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Stores \tcode{bytebuf} in \tcode{bufptr}. + +\pnum +\returns The previous value of \tcode{bufptr}. +\end{itemdescr} + +\indexlibrarymember{state_type}{wbuffer_convert}% +\begin{itemdecl} +using state_type = typename Codecvt::state_type; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type shall be a synonym for \tcode{Codecvt::state_type}. +\end{itemdescr} + +\indexlibrary{\idxcode{wbuffer_convert}!constructor}% +\begin{itemdecl} +explicit wbuffer_convert( + streambuf* bytebuf = 0, + Codecvt* pcvt = new Codecvt, + state_type state = state_type()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\tcode{pcvt != nullptr}. + +\pnum +\effects The constructor constructs a stream buffer object, initializes +\tcode{bufptr} to \tcode{bytebuf}, initializes \tcode{cvtptr} +to \tcode{pcvt}, and initializes \tcode{cvtstate} to \tcode{state}. +\end{itemdescr} + +\indexlibrary{\idxcode{wbuffer_convert}!destructor}% +\begin{itemdecl} +~wbuffer_convert(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects The destructor shall delete \tcode{cvtptr}. +\end{itemdescr} diff --git a/source/grammar.tex b/source/grammar.tex index 7e67ae4a7d..7ac4257d2f 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -54,9 +54,9 @@ \end{ncbnf} Note that a -\grammarterm{typedef-name}\ +\grammarterm{typedef-name}\ naming a class is also a -\grammarterm{class-name}\ +\grammarterm{class-name}\ (\ref{class.name}). \FlushAndPrintGrammar diff --git a/source/intro.tex b/source/intro.tex index bf9e508cb8..d309ed55be 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -1,39 +1,14 @@ %!TEX root = std.tex -\rSec0[intro]{General} -\indextext{diagnostic message|see{message, diagnostic}}% -\indexdefn{conditionally-supported behavior|see{behavior, con\-ditionally-supported}}% -\indextext{dynamic type|see{type, dynamic}}% -\indextext{static type|see{type, static}}% -\indextext{ill-formed program|see{program, ill-formed}}% -\indextext{well-formed program|see{program, well-formed}}% -\indextext{implementation-defined behavior|see{behavior, im\-plementation-defined}}% -\indextext{undefined behavior|see{behavior, undefined}}% -\indextext{unspecified behavior|see{behavior, unspecified}}% -\indextext{implementation limits|see{limits, implementation}}% -\indextext{locale-specific behavior|see{behavior, locale-spe\-cific}}% -\indextext{multibyte character|see{character, multibyte}}% -\indextext{object|seealso{object model}}% -\indextext{subobject|seealso{object model}}% -\indextext{derived class!most|see{most derived class}}% -\indextext{derived object!most|see{most derived object}}% -\indextext{program execution!as-if rule|see{as-if rule}}% -\indextext{observable behavior|see{behavior, observable}}% -\indextext{precedence of operator|see{operator, precedence of}}% -\indextext{order of evaluation in expression|see{expression, order of evaluation of}}% -\indextext{atomic operations|see{operation, atomic}}% -\indextext{multiple threads|see{threads, multiple}}% -\indextext{normative references|see{references, normative}} - -\rSec1[intro.scope]{Scope} +\rSec0[intro.scope]{Scope} \pnum \indextext{scope|(}% -This International Standard specifies requirements for implementations +This document specifies requirements for implementations of the \Cpp programming language. The first such requirement is that -they implement the language, so this International Standard also +they implement the language, so this document also defines \Cpp. Other requirements and relaxations of the first -requirement appear at various places within this International Standard. +requirement appear at various places within this document. \pnum \Cpp is a general purpose programming language based on the C @@ -46,11 +21,14 @@ management operators, and additional library facilities.% \indextext{scope|)} -\rSec1[intro.refs]{Normative references} +\indextext{normative references|see{references, normative}}% +\rSec0[intro.refs]{Normative references} \pnum \indextext{references!normative|(}% -The following referenced documents are indispensable for the application +The following documents are referred to in the text +in such a way that some or all of their content +constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies. @@ -67,8 +45,11 @@ \item ISO/IEC 10646-1:1993, \doccite{Information technology --- Universal Multiple-Octet Coded Character Set (UCS) --- Part 1: Architecture and Basic Multilingual Plane} -%\item IEC 60559:1989, \doccite{Binary floating-point arithmetic for -%microprocessor systems} +\item ISO/IEC 10967-1:2012, \doccite{Information technology --- +Language independent arithmetic --- Part 1: +Integer and floating point arithmetic} +\item ISO/IEC/IEEE 60559:2011, \doccite{Information technology --- +Microprocessor Systems --- Floating-Point arithmetic} \item ISO 80000-2:2009, \doccite{Quantities and units --- Part 2: Mathematical signs and symbols to be used in the natural sciences and technology} @@ -89,18 +70,31 @@ \pnum The ECMAScript Language Specification described in Standard Ecma-262 is hereinafter called \defn{ECMA-262}. + +\pnum +The arithmetic specification described in ISO/IEC 10967-1:2012 is +hereinafter called \defn{LIA-1}. \indextext{references!normative|)} -\rSec1[intro.defs]{Terms and definitions} +\rSec0[intro.defs]{Terms and definitions} \pnum \indextext{definitions|(}% For the purposes of this document, the terms and definitions -given in ISO/IEC 2382-1:1993 and +given in ISO/IEC 2382-1:1993, the terms, definitions, and symbols -given in ISO 80000-2:2009 apply, -as do the following definitions. +given in ISO 80000-2:2009, +and the following apply. + +\pnum +ISO and IEC maintain terminological databases +for use in standardization +at the following addresses: +\begin{itemize} +\item IEC Electropedia: available at \url{http://www.electropedia.org/} +\item ISO Online browsing platform: available at \url{http://www.iso.org/obp} +\end{itemize} \pnum \ref{definitions} @@ -108,10 +102,12 @@ through~\ref{\lastlibchapter} and Annex~\ref{depr}. \pnum -Terms that are used only in a small portion of this International -Standard are defined where they are used and italicized where they are +Terms that are used only in a small portion of this document +are defined where they are used and italicized where they are defined. +\def\definition{\definitionx{\section}}% + \indexdefn{access}% \definition{access}{defns.access} \defncontext{execution-time action} to read or modify the value of an object @@ -300,6 +296,30 @@ semantic rules, and the one-definition rule~(\ref{basic.def.odr}).% \indextext{definitions|)} +\rSec0[intro]{General principles} + +\indextext{diagnostic message|see{message, diagnostic}}% +\indexdefn{conditionally-supported behavior|see{behavior, con\-ditionally-supported}}% +\indextext{dynamic type|see{type, dynamic}}% +\indextext{static type|see{type, static}}% +\indextext{ill-formed program|see{program, ill-formed}}% +\indextext{well-formed program|see{program, well-formed}}% +\indextext{implementation-defined behavior|see{behavior, im\-plementation-defined}}% +\indextext{undefined behavior|see{behavior, undefined}}% +\indextext{unspecified behavior|see{behavior, unspecified}}% +\indextext{implementation limits|see{limits, implementation}}% +\indextext{locale-specific behavior|see{behavior, locale-spe\-cific}}% +\indextext{multibyte character|see{character, multibyte}}% +\indextext{object|seealso{object model}}% +\indextext{subobject|seealso{object model}}% +\indextext{derived class!most|see{most derived class}}% +\indextext{derived object!most|see{most derived object}}% +\indextext{program execution!as-if rule|see{as-if rule}}% +\indextext{observable behavior|see{behavior, observable}}% +\indextext{precedence of operator|see{operator, precedence of}}% +\indextext{order of evaluation in expression|see{expression, order of evaluation of}}% +\indextext{atomic operations|see{operation, atomic}}% +\indextext{multiple threads|see{threads, multiple}}% \rSec1[intro.compliance]{Implementation compliance} \pnum @@ -323,7 +343,7 @@ If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute\footnote{``Correct execution'' can include undefined behavior, depending on -the data being processed; see~\ref{intro.defs} and~\ref{intro.execution}.} +the data being processed; see Clause~\ref{intro.defs} and~\ref{intro.execution}.} that program. \item \indextext{message!diagnostic}% @@ -396,7 +416,7 @@ \indextext{conformance requirements!general|)}% \indextext{conformance requirements|)}% -\rSec1[intro.structure]{Structure of this International Standard} +\rSec1[intro.structure]{Structure of this document} \pnum \indextext{standard!structure of|(}% @@ -424,7 +444,7 @@ purposes; Annex~\ref{depr} describes those features. \pnum -Throughout this International Standard, each example is introduced by +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.% @@ -434,7 +454,7 @@ \pnum \indextext{notation!syntax|(}% -In the syntax notation used in this International Standard, syntactic +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 @@ -541,7 +561,7 @@ by a \grammarterm{new-expression}~(\ref{expr.new}), when implicitly changing the active member of a union~(\ref{class.union}), or -when a temporary object is created~(\ref{conv.rval}, \ref{class.temporary}). +when a temporary object is created~(\ref{conv.rval}, \ref{class.temporary}). An object occupies a region of storage in its period of construction~(\ref{class.cdtor}), throughout its lifetime~(\ref{basic.life}), @@ -608,7 +628,8 @@ \indextext{object!providing storage for}% If a complete object is created~(\ref{expr.new}) in storage associated with another object \placeholder{e} -of type ``array of $N$ \tcode{unsigned char}'', +of type ``array of $N$ \tcode{unsigned char}'' or +of type ``array of $N$ \tcode{std::byte}''~(\ref{cstddef.syn}), that array \defn{provides storage} for the created object if: \begin{itemize} @@ -718,7 +739,7 @@ \end{example} \pnum -\begin{note} +\begin{note} \Cpp provides a variety of fundamental types and several ways of composing new types from existing types~(\ref{basic.types}). \end{note}% @@ -785,23 +806,13 @@ A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the -same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no +same program and the same input. +\indextext{behavior!undefined}% +However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation). -\indextext{behavior!unspecified}% -\indextext{behavior!undefined}% -\indextext{behavior!on receipt of signal}% -\indextext{signal}% -\pnum -If a signal handler is executed as a result of a call to the \tcode{std::raise} -function, then the execution of the handler is sequenced after the invocation -of the \tcode{std::raise} function and before its return. -\begin{note} When a signal is received for another reason, the execution of the -signal handler is usually unsequenced with respect to the rest of the program. -\end{note} - \pnum An instance of each object with automatic storage duration~(\ref{basic.stc.auto}) is associated with each entry into its @@ -814,7 +825,7 @@ The least requirements on a conforming implementation are: \begin{itemize} \item -Access to volatile objects are evaluated strictly according to the +Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine. \item At program termination, all data written into files shall be @@ -1006,7 +1017,7 @@ 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 to a \tcode{volatile} object is evaluated the side +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. @@ -1114,6 +1125,16 @@ 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} @@ -1231,7 +1252,7 @@ \tcode{std::kill_dependency}~(\ref{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}) +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}) @@ -1243,7 +1264,7 @@ \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 +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'', @@ -1318,6 +1339,20 @@ 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 @@ -1469,12 +1504,12 @@ \rSec2[intro.progress]{Forward progress} \pnum -The implementation may assume that any thread will eventually do one of the +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 read or modify a volatile object, or +\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 @@ -1516,7 +1551,7 @@ under expected operating conditions, and that such anomalies can therefore safely be ignored by programmers. - Outside this International Standard, + Outside this document, this property is sometimes termed lock-free. \end{note} \end{itemize} @@ -1526,7 +1561,7 @@ an \defn{execution step}: \begin{itemize} \item termination of the thread of execution, -\item access to a volatile object, or +\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} @@ -1672,8 +1707,8 @@ \rSec1[intro.ack]{Acknowledgments} \pnum -The \Cpp programming language as described in this International -Standard is based on the language as described in Chapter R (Reference +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 edition, Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright \copyright 1991 AT\&T). That, in turn, is based on the C @@ -1682,7 +1717,7 @@ 0-13-110163-3, copyright \copyright 1978 AT\&T). \pnum -Portions of the library Clauses of this International Standard are based +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 \copyright 1995 P.J. Plauger). @@ -1691,5 +1726,8 @@ POSIX\textregistered\ is a registered trademark of the Institute of Electrical and Electronic Engineers, Inc. +\pnum +ECMAScript\textregistered\ is a registered trademark of Ecma International. + \pnum All rights in these originals are reserved. diff --git a/source/iostreams.tex b/source/iostreams.tex index 64f0d0ddef..5b5f008b1d 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1110,7 +1110,7 @@ class ios_base::Init { public: Init(); - ~Init(); + ~Init(); private: static int init_cnt; // \expos }; @@ -2219,7 +2219,7 @@ then \tcode{state == rdstate()}; otherwise -\tcode{rdstate() == (state | ios_base\colcol{}badbit)}. +\tcode{rdstate() == (state | ios_base::badbit)}. \pnum \effects @@ -3251,7 +3251,7 @@ returns \tcode{underflow()}. Otherwise, returns -\tcode{traits\colcol{}to_int_type(*gptr())}. +\tcode{traits::to_int_type(*gptr())}. \end{itemdescr} \indexlibrarymember{sgetn}{basic_streambuf}% @@ -4123,6 +4123,10 @@ template @\textit{T13}@ quoted(basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); + + template + @\textit{T14}@ quoted(basic_string_view s, + @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); } \end{codeblock} @@ -7018,7 +7022,8 @@ \begin{itemdescr} \pnum -\requires The argument \tcode{tmb} shall be a valid pointer to an object of type \tcode{struct tm}, and the argument \tcode{fmt} shall be a valid pointer to an array of objects of type \tcode{charT} with \tcode{char_traits::length(fmt)} elements. +\requires The argument \tcode{tmb} shall be a valid pointer to an object of type \tcode{struct tm}. +The argument \tcode{fmt} shall be a valid pointer to an array of objects of type \tcode{charT} with \tcode{char_traits::length(fmt)} elements. \pnum \returns An object of unspecified type such that if \tcode{in} is an object of type @@ -7096,14 +7101,17 @@ template @\unspec@ quoted(const basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); +template + @\unspec@ quoted(basic_string_view s, + @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an instance of \tcode{basic_ostream} with member type \tcode{char_type} the same as -\tcode{charT} and with member type \tcode{traits_type}, which in the second -form is the same as \tcode{traits}, then the expression +\tcode{charT} and with member type \tcode{traits_type}, which in the second and third +forms is the same as \tcode{traits}, then the expression \tcode{out << quoted(s, delim, escape)} behaves as a formatted output function~(\ref{ostream.formatted.reqmts}) of \tcode{out}. This forms a character sequence \tcode{seq}, initially @@ -7458,7 +7466,7 @@ \tcode{str(basic_string)} member function, all characters initialized prior to the call are now considered uninitialized (except for those characters re-initialized by the new \tcode{basic_string}). Otherwise the \tcode{basic_stringbuf} has been created -in neither input nor output mode and a zero length \tcode{basic_string} is returned. +in neither input nor output mode and a zero length \tcode{basic_string} is returned. \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% @@ -7498,7 +7506,7 @@ Otherwise, returns \tcode{traits::eof()}. Any character in the underlying buffer which has been initialized is considered -to be part of the input sequence. +to be part of the input sequence. \end{itemdescr} \indexlibrarymember{pbackfail}{basic_stringbuf}% @@ -7650,9 +7658,9 @@ \begin{libtab2}{\tcode{seekoff} positioning}{tab:iostreams.seekoff.positioning} {p{2.5in}l}{Conditions}{Result} -\tcode{(which \& ios_base\colcol{}in)}\tcode{ == ios_base::in} & +\tcode{(which \& ios_base::in)}\tcode{ == ios_base::in} & positions the input sequence \\ \rowsep -\tcode{(which \& ios_base\colcol{}out)}\tcode{ == ios_base::out} & +\tcode{(which \& ios_base::out)}\tcode{ == ios_base::out} & positions the output sequence \\ \rowsep \tcode{(which \& (ios_base::in |}\br \tcode{ios_base::out)) ==}\br @@ -8262,7 +8270,7 @@ \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs} by calling -\tcode{basic_iostream::swap(rhs)} and +\tcode{basic_iostream::swap(rhs)} and \tcode{sb.swap(rhs.sb)}. \end{itemdescr} @@ -8374,6 +8382,13 @@ object converts those multibyte sequences into wide character sequences. \end{note} +\pnum +In this subclause, member functions taking arguments of \tcode{const filesystem::path::value_type*} +are only be provided on systems where \tcode{filesystem::path::value_type}~(\ref{fs.class.path}) is not \tcode{char}. +\begin{note} +These functions enable class \tcode{path} support for systems with a wide native path character type, such as \tcode{wchar_t}. +\end{note} + \rSec2[filebuf]{Class template \tcode{basic_filebuf}} \indexlibrary{\idxcode{basic_filebuf}}% @@ -8401,11 +8416,14 @@ // \ref{filebuf.members}, members bool is_open() const; - basic_filebuf* open(const char* s, - ios_base::openmode mode); - basic_filebuf* open(const string& s, - ios_base::openmode mode); - basic_filebuf* close(); + basic_filebuf* open(const char* s, ios_base::openmode mode); + basic_filebuf* open(const filesystem::path::value_type* s, + ios_base::openmode mode); // wide systems only; see \ref{fstream.syn} + basic_filebuf* open(const string& s, + ios_base::openmode mode); + basic_filebuf* open(const filesystem::path& s, + ios_base::openmode mode); + basic_filebuf* close(); protected: // \ref{filebuf.virtuals}, overridden virtual functions @@ -8466,7 +8484,7 @@ behaves as described in~\ref{filebuf} provided \tcode{traits::pos_type} is -\tcode{fpos}. +\tcode{fpos}. Otherwise the behavior is undefined. \pnum @@ -8614,8 +8632,9 @@ \indexlibrarymember{open}{basic_filebuf}% \begin{itemdecl} -basic_filebuf* open(const char* s, - ios_base::openmode mode); +basic_filebuf* open(const char* s, ios_base::openmode mode); +basic_filebuf* open(const filesystem::path::value_type* s, + ios_base::openmode mode); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -8696,8 +8715,8 @@ \indexlibrarymember{open}{basic_filebuf}% \begin{itemdecl} -basic_filebuf* open(const string& s, - ios_base::openmode mode); +basic_filebuf* open(const string& s, ios_base::openmode mode); +basic_filebuf* open(const filesystem::path& s, ios_base::openmode mode); \end{itemdecl} \begin{itemdescr} @@ -8708,7 +8727,7 @@ \indexlibrarymember{close}{basic_filebuf}% \begin{itemdecl} -basic_filebuf* close(); +basic_filebuf* close(); \end{itemdecl} \begin{itemdescr} @@ -9157,8 +9176,12 @@ basic_ifstream(); explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const filesystem::path& s, + ios_base::openmode mode = ios_base::in); basic_ifstream(const basic_ifstream& rhs) = delete; basic_ifstream(basic_ifstream&& rhs); @@ -9172,7 +9195,10 @@ bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::in); + void open(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} void open(const string& s, ios_base::openmode mode = ios_base::in); + void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); void close(); private: basic_filebuf sb; // \expos @@ -9222,6 +9248,8 @@ \begin{itemdecl} explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); +explicit basic_ifstream(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9244,6 +9272,8 @@ \begin{itemdecl} explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); +explicit basic_ifstream(const filesystem::path& s, + ios_base::openmode mode = ios_base::in); \end{itemdecl} \begin{itemdescr} @@ -9333,6 +9363,8 @@ \indexlibrarymember{open}{basic_ifstream}% \begin{itemdecl} void open(const char* s, ios_base::openmode mode = ios_base::in); +void open(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9351,6 +9383,7 @@ \indexlibrarymember{open}{basic_ifstream}% \begin{itemdecl} void open(const string& s, ios_base::openmode mode = ios_base::in); +void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); \end{itemdecl} \begin{itemdescr} @@ -9394,8 +9427,12 @@ basic_ofstream(); explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const filesystem::path& s, + ios_base::openmode mode = ios_base::out); basic_ofstream(const basic_ofstream& rhs) = delete; basic_ofstream(basic_ofstream&& rhs); @@ -9409,7 +9446,10 @@ bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::out); + void open(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} void open(const string& s, ios_base::openmode mode = ios_base::out); + void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out); void close(); private: basic_filebuf sb; // \expos @@ -9458,6 +9498,8 @@ \begin{itemdecl} explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); +explicit basic_ofstream(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9480,6 +9522,8 @@ \begin{itemdecl} explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); +explicit basic_ofstream(const filesystem::path& s, + ios_base::openmode mode = ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -9569,6 +9613,8 @@ \indexlibrarymember{open}{basic_ofstream}% \begin{itemdecl} void open(const char* s, ios_base::openmode mode = ios_base::out); +void open(const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9603,6 +9649,7 @@ \indexlibrarymember{open}{basic_ofstream}% \begin{itemdecl} void open(const string& s, ios_base::openmode mode = ios_base::out); +void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -9629,9 +9676,15 @@ explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); + explicit basic_fstream( + const std::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, ios_base::openmode mode = ios_base::in | ios_base::out); + explicit basic_fstream( + const filesystem::path& s, + ios_base::openmode mode = ios_base::in | ios_base::out); basic_fstream(const basic_fstream& rhs) = delete; basic_fstream(basic_fstream&& rhs); @@ -9646,9 +9699,15 @@ void open( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); + void open( + const std::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, ios_base::openmode mode = ios_base::in | ios_base::out); + void open( + const filesystem::path& s, + ios_base::openmode mode = ios_base::in | ios_base::out); void close(); private: @@ -9700,6 +9759,9 @@ explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); +explicit basic_fstream( + const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9724,6 +9786,9 @@ explicit basic_fstream( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); +explicit basic_fstream( + const filesystem::path& s, + ios_base::openmode mode = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -9770,7 +9835,7 @@ \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs} by calling -\tcode{basic_iostream::swap(rhs)} and +\tcode{basic_iostream::swap(rhs)} and \tcode{sb.swap(rhs.sb)}. \end{itemdescr} @@ -9815,6 +9880,9 @@ void open( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); +void open( + const filesystem::path::value_type* s, + ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} @@ -9834,6 +9902,9 @@ void open( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); +void open( + const filesystem::path& s, + ios_base::openmode mode = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -9897,7 +9968,9 @@ \begin{example} The FAT file system used by some memory cards, camera memory, and floppy disks does not support hard links, symlinks, and many other features of more capable file systems, so implementations are not required to support those -features on the FAT file system. \end{example} +features on the FAT file system +but instead are required to report an error as described above. +\end{example} \rSec3[fs.conform.os]{Operating system dependent behavior conformance} \pnum @@ -9937,39 +10010,39 @@ \rSec2[fs.definitions]{Terms and definitions} -\definitionx{absolute path}{fs.def.absolute.path} +\def\definition{\definitionx{\subsubsection}}% + +\definition{absolute path}{fs.def.absolute.path} A path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path that determine if it is absolute are operating system dependent. -\definitionx{canonical path}{fs.def.canonical.path} -An absolute path that has no elements that are symbolic links, and no \grammarterm{dot} or -\grammarterm{dot-dot} elements~(\ref{path.generic}). - -\definitionx{directory}{fs.def.directory} +\definition{directory}{fs.def.directory} A file within a file system that acts as a container of directory entries that contain information about other files, possibly including other directory files. -\definitionx{file}{fs.def.file} +\definition{file}{fs.def.file} An object within a file system that holds user or system data. Files can be written to, or read from, or both. A file has certain attributes, including type. File types include regular files and directories. Other types of files, such as symbolic links~(\ref{fs.def.symlink}), may be supported by the implementation. -\definitionx{file system}{fs.def.filesystem} -A collection of files and certain of their attributes. +\definition{file system}{fs.def.filesystem} +A collection of files and their attributes. -\definitionx{file system race}{fs.def.race} +\definition{file system race}{fs.def.race} The condition that occurs when multiple threads, processes, or computers interleave access and modification of the same object within a file system. -\definitionx{filename}{fs.def.filename} -The name of a file. Filenames \grammarterm{dot} and \grammarterm{dot-dot} have special meaning. The -following characteristics of filenames are operating system dependent: +\definition{filename}{fs.def.filename} +The name of a file. Filenames \grammarterm{dot} and \grammarterm{dot-dot}, +consisting solely of one and two period characters respectively, +have special meaning. +The following characteristics of filenames are operating system dependent: \begin{itemize} \item The permitted characters. \begin{example} Some operating systems prohibit the ASCII control characters (0x00 -- 0x1F) in filenames. \end{example} @@ -9981,78 +10054,84 @@ files, such as directories. \end{itemize} -\definitionx{hard link}{fs.def.hardlink} +\definition{hard link}{fs.def.hardlink} A link~(\ref{fs.def.link}) to an existing file. Some file systems support multiple hard links to a file. If the last hard link to a file is removed, the file itself is removed. \begin{note} A hard link can be thought of as a shared-ownership smart pointer to a file.\end{note} -\definitionx{link}{fs.def.link} -A directory entry that associates a -filename with a file. A link is either a hard link~(\ref{fs.def.hardlink}) or a -symbolic link~(\ref{fs.def.symlink}). +\definition{link}{fs.def.link} +An object that associates a filename with a file. Several links can associate names with the same file. -\definitionx{native encoding}{fs.def.native.encode} +\definition{native encoding}{fs.def.native.encode} For narrow character strings, the operating system dependent current encoding for pathnames~(\ref{fs.def.pathname}). For wide character strings, the implementation-defined execution wide-character set encoding~(\ref{lex.charset}). -\definitionx{native pathname format}{fs.def.native} +\definition{native pathname format}{fs.def.native} The operating system dependent pathname format accepted by the host operating system. -\definitionx{normal form}{fs.def.normal.form} -A path with no redundant current directory (\grammarterm{dot}) elements, -no redundant parent directory (\grammarterm{dot-dot}) elements, and -no redundant \grammarterm{directory-separator}{s}. -The normal form for an empty path is an empty path. -The normal form for a path ending in a \grammarterm{directory-separator} -that is not the root directory -has a current directory (\grammarterm{dot}) element appended. +\definition{normal form}{fs.def.normal.form} A path in normal form is said to be \term{normalized}. The process of obtaining a normalized path from a path that is not in normal form is called \term{normalization}. -\begin{note} The rule that appends a current directory (\grammarterm{dot}) element -supports operating systems like OpenVMS -that use different syntax for directory names and regular file names. + +Normalization of a generic format pathname means: + +\begin{enumerate} +\item If the path is empty, stop. +\item Replace each slash character in the \grammarterm{root-name} with a \grammarterm{preferred-separator}. +\item Replace each \grammarterm{directory-separator} with a \grammarterm{preferred-separator}. +\begin{note} +The generic pathname grammar~(\ref{fs.path.generic}) defines \grammarterm{directory-separator} as one or more slashes and \grammarterm{preferred-separator}{s}. +\end{note} +\item Remove each \grammarterm{dot} filename and any immediately following \grammarterm{directory-separator}. +\item As long as any appear, remove a non-\grammarterm{dot-dot} filename immediately followed by a \grammarterm{directory-separator} and a \grammarterm{dot-dot} filename, along with any immediately following \grammarterm{directory-separator}. +\item If there is a \grammarterm{root-directory}, remove all \grammarterm{dot-dot} filenames and any \grammarterm{directory-separator}{s} immediately following them. +\begin{note} +These \grammarterm{dot-dot} filenames attempt to refer to nonexistent parent directories. \end{note} +\item If the last filename is \grammarterm{dot-dot}, remove any trailing \grammarterm{directory-separator}. +\item If the path is empty, add a \grammarterm{dot}. +\end{enumerate} -\definitionx{operating system dependent behavior}{fs.def.osdep} +\definition{operating system dependent behavior}{fs.def.osdep} Behavior that is dependent upon the behavior and characteristics of an operating system. See~\ref{fs.conform.os}. -\definitionx{parent directory}{fs.def.parent} +\definition{parent directory}{fs.def.parent} \defncontext{of a directory} the directory that both contains a directory entry for the given directory and is represented by the filename \grammarterm{dot-dot} in the given directory. -\definitionx{parent directory}{fs.def.parent.other} +\definition{parent directory}{fs.def.parent.other} \defncontext{of other types of files} a directory containing a directory entry for the file under discussion. -\definitionx{path}{fs.def.path} +\definition{path}{fs.def.path} 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}, +\grammarterm{root-name}\opt{}, +\grammarterm{root-directory}\opt{}, and an optional sequence of filenames. The maximum number of elements in the sequence is operating system dependent. -\definitionx{pathname}{fs.def.pathname} +\definition{pathname}{fs.def.pathname} A character string that represents the name of a path. Pathnames are -formatted according to the generic pathname format grammar~(\ref{path.generic}) or an +formatted according to the generic pathname format grammar~(\ref{fs.path.generic}) or an operating system dependent native pathname format. -\definitionx{pathname resolution}{fs.def.pathres} +\definition{pathname resolution}{fs.def.pathres} Pathname resolution is the operating system dependent mechanism for resolving a pathname to a particular file in a file hierarchy. There may be multiple pathnames that resolve to the same file. \begin{example} POSIX specifies the mechanism in section 4.11, Pathname resolution. \end{example} -\definitionx{relative path}{fs.def.relative-path} +\definition{relative path}{fs.def.rel.path} A path that is not absolute, and as such, only unambiguously identifies the location of a file when resolved~(\ref{fs.def.pathres}) relative to an implied starting location. The elements of a path that determine if it is @@ -10061,7 +10140,7 @@ Pathnames ``.'' and ``..'' are relative paths. \end{note} -\definitionx{symbolic link}{fs.def.symlink} +\definition{symbolic link}{fs.def.symlink} A type of file with the property that when the file is encountered during pathname resolution, a string stored by the file is used to modify the pathname resolution. @@ -10088,8 +10167,10 @@ \pnum \begin{note} Use of an encoded character type implies an associated -encoding. Since \tcode{signed char} and \tcode{unsigned char} have no -implied encoding, they are not included as permitted types. \end{note} +character set and encoding. +Since \tcode{signed char} and \tcode{unsigned char} have no +implied character set and encoding, +they are not included as permitted types. \end{note} \pnum Template parameters named \tcode{Allocator} shall meet the @@ -10107,10 +10188,10 @@ \begin{codeblock} namespace std::filesystem { - // \ref{class.path}, paths + // \ref{fs.class.path}, paths class path; - // \ref{path.non-member}, path non-member functions + // \ref{fs.path.nonmember}, \tcode{path} non-member functions void swap(path& lhs, path& rhs) noexcept; size_t hash_value(const path& p) noexcept; @@ -10123,7 +10204,7 @@ path operator/ (const path& lhs, const path& rhs); - // \ref{path.io}, path inserter and extractor + // \ref{fs.path.io}, \tcode{path} inserter and extractor template basic_ostream& operator<<(basic_ostream& os, const path& p); @@ -10131,33 +10212,33 @@ basic_istream& operator>>(basic_istream& is, path& p); - // \ref{path.factory}, path factory functions + // \ref{fs.path.factory}, \tcode{path} factory functions template path u8path(const Source& source); template path u8path(InputIterator first, InputIterator last); - // \ref{class.filesystem_error}, filesystem errors + // \ref{fs.class.filesystem_error}, filesystem errors class filesystem_error; - // \ref{class.directory_entry}, directory entries + // \ref{fs.class.directory_entry}, directory entries class directory_entry; - // \ref{class.directory_iterator}, directory iterators + // \ref{fs.class.directory_iterator}, directory iterators class directory_iterator; - // \ref{directory_iterator.nonmembers}, range access for directory iterators + // \ref{fs.dir.itr.nonmembers}, range access for directory iterators directory_iterator begin(directory_iterator iter) noexcept; directory_iterator end(const directory_iterator&) noexcept; - // \ref{class.rec.dir.itr}, recursive directory iterators + // \ref{fs.class.rec.dir.itr}, recursive directory iterators class recursive_directory_iterator; - // \ref{rec.dir.itr.nonmembers}, range access for recursive directory iterators + // \ref{fs.rec.dir.itr.nonmembers}, range access for recursive directory iterators recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; - // \ref{class.file_status}, file status + // \ref{fs.class.file_status}, file status class file_status; struct space_info { @@ -10169,6 +10250,7 @@ // \ref{fs.enum}, enumerations enum class file_type; enum class perms; + enum class perm_options; enum class copy_options; enum class directory_options; @@ -10278,8 +10360,9 @@ void last_write_time(const path& p, file_time_type new_time, error_code& ec) noexcept; - void permissions(const path& p, perms prms); - void permissions(const path& p, perms prms, error_code& ec); + void permissions(const path& p, perms prms, perm_options opts=perm_options::replace); + void permissions(const path& p, perms prms, error_code& ec) noexcept; + void permissions(const path& p, perms prms, perm_options opts, error_code& ec); path proximate(const path& p, error_code& ec); path proximate(const path& p, const path& base = current_path()); @@ -10315,9 +10398,6 @@ file_status symlink_status(const path& p); file_status symlink_status(const path& p, error_code& ec) noexcept; - path system_complete(const path& p); - path system_complete(const path& p, error_code& ec); - path temp_directory_path(); path temp_directory_path(error_code& ec); @@ -10388,7 +10468,7 @@ \tcode{error_code\&} argument. \end{itemize} -\rSec2[class.path]{Class \tcode{path}} +\rSec2[fs.class.path]{Class \tcode{path}} \indexlibrary{\idxcode{path}}% \pnum @@ -10399,6 +10479,11 @@ pathname is not necessarily valid for the current operating system or for a particular file system. +\pnum +\begin{note} +Class \tcode{path} is used to support the differences between the string types used by different operating systems to represent pathnames, and to perform conversions between encodings when necessary. +\end{note} + \begin{codeblock} namespace std::filesystem { class path { @@ -10407,22 +10492,25 @@ using string_type = basic_string; static constexpr value_type preferred_separator = @\seebelow@; - // \ref{path.construct}, constructors and destructor + // \ref{fs.enum.path.format}, enumeration \tcode{format} + enum format; + + // \ref{fs.path.construct}, constructors and destructor path() noexcept; path(const path& p); path(path&& p) noexcept; - path(string_type&& source); + path(string_type&& source, format fmt = auto_format); template - path(const Source& source); + path(const Source& source, format fmt = auto_format); template - path(InputIterator first, InputIterator last); + path(InputIterator first, InputIterator last, format fmt = auto_format); template - path(const Source& source, const locale& loc); + path(const Source& source, const locale& loc, format fmt = auto_format); template - path(InputIterator first, InputIterator last, const locale& loc); - ~path(); + path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); + ~path(); - // \ref{path.assign}, assignments + // \ref{fs.path.assign}, assignments path& operator=(const path& p); path& operator=(path&& p) noexcept; path& operator=(string_type&& source); @@ -10434,7 +10522,7 @@ template path& assign(InputIterator first, InputIterator last); - // \ref{path.append}, appends + // \ref{fs.path.append}, appends path& operator/=(const path& p); template path& operator/=(const Source& source); @@ -10443,7 +10531,7 @@ template path& append(InputIterator first, InputIterator last); - // \ref{path.concat}, concatenation + // \ref{fs.path.concat}, concatenation path& operator+=(const path& x); path& operator+=(const string_type& x); path& operator+=(basic_string_view x); @@ -10458,7 +10546,7 @@ template path& concat(InputIterator first, InputIterator last); - // \ref{path.modifiers}, modifiers + // \ref{fs.path.modifiers}, modifiers void clear() noexcept; path& make_preferred(); path& remove_filename(); @@ -10466,7 +10554,7 @@ path& replace_extension(const path& replacement = path()); void swap(path& rhs) noexcept; - // \ref{path.native.obs}, native format observers + // \ref{fs.path.native.obs}, native format observers const string_type& native() const noexcept; const value_type* c_str() const noexcept; operator string_type() const; @@ -10481,7 +10569,7 @@ std::u16string u16string() const; std::u32string u32string() const; - // \ref{path.generic.obs}, generic format observers + // \ref{fs.path.generic.obs}, generic format observers template , class Allocator = allocator> basic_string @@ -10492,13 +10580,13 @@ std::u16string generic_u16string() const; std::u32string generic_u32string() const; - // \ref{path.compare}, compare + // \ref{fs.path.compare}, compare int compare(const path& p) const noexcept; int compare(const string_type& s) const; int compare(basic_string_view s) const; int compare(const value_type* s) const; - // \ref{path.decompose}, decomposition + // \ref{fs.path.decompose}, decomposition path root_name() const; path root_directory() const; path root_path() const; @@ -10508,7 +10596,7 @@ path stem() const; path extension() const; - // \ref{path.query}, query + // \ref{fs.path.query}, query bool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; @@ -10521,20 +10609,17 @@ bool is_absolute() const; bool is_relative() const; - // \ref{path.gen}, generation + // \ref{fs.path.gen}, generation path lexically_normal() const; path lexically_relative(const path& base) const; path lexically_proximate(const path& base) const; - // \ref{path.itr}, iterators + // \ref{fs.path.itr}, iterators class iterator; using const_iterator = iterator; iterator begin() const; iterator end() const; - - private: - string_type pathstring; // \expos }; } \end{codeblock} @@ -10546,8 +10631,8 @@ \indexlibrarymember{preferred_separator}{path}% \pnum -The value of \tcode{preferred_separator} -is the operating system dependent \grammarterm{preferred-separator} character~(\ref{path.generic}). +The value of the \tcode{preferred_separator} member +is the operating system dependent \grammarterm{preferred-separator} character~(\ref{fs.path.generic}). \pnum \begin{example} @@ -10559,28 +10644,20 @@ \tcode{preferred_separator} is the backslash character (\tcode{L'\textbackslash\textbackslash'}). \end{example} -\rSec3[path.generic]{Generic pathname format} +\rSec3[fs.path.generic]{Generic pathname format} + +\def\impldefrootname{\impldef{supported \grammarterm{root-name}{s} in addition to +any operating system dependent \grammarterm{root-name}{s}}} \begin{ncbnf} \nontermdef{pathname}\br - root-name root-directory\opt relative-path\opt\br - root-directory relative-path\opt\br - relative-path + root-name\opt{} root-directory\opt{} relative-path \end{ncbnf} \begin{ncbnf} \nontermdef{root-name}\br - \textnormal{An operating system dependent name that identifies the starting location for absolute paths. -\begin{note} Many operating systems define a name -beginning with two \grammarterm{directory-separator} characters -as a \grammarterm{root-name} that identifies -network or other resource locations. -Some operating systems -define a single letter followed by a colon -as a drive specifier -- a \grammarterm{root-name} -identifying a specific device such as a disk drive. -\end{note} -} + \textnormal{operating system dependent sequences of characters}\br + \textnormal{\impldefrootname{} sequences of characters} \end{ncbnf} \begin{ncbnf} @@ -10591,79 +10668,86 @@ \begin{ncbnf} \nontermdef{relative-path}\br filename\br - relative-path directory-separator\br - relative-path directory-separator filename + filename directory-separator relative-path\br + \textnormal{an empty path} \end{ncbnf} \begin{ncbnf} \nontermdef{filename}\br - name\br - dot\br - dot-dot -\end{ncbnf} - -\begin{ncbnf} -\nontermdef{name}\br - \textnormal{A sequence of characters other than \grammarterm{directory-separator} characters. -\begin{note} -Operating systems often place restrictions -on the characters that may be used in a \grammarterm{filename}. -For wide portability, users may wish to limit \grammarterm{filename} -characters to the POSIX Portable Filename Character Set: \\ -\tcode{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} \\ -\tcode{a b c d e f g h i j k l m n o p q r s t u v w x y z} \\ -\tcode{0 1 2 3 4 5 6 7 8 9 . _ -} -\end{note} -} -\end{ncbnf} - -\begin{ncbnf} -\nontermdef{dot}\br - \textnormal{The filename consisting solely of a single period character (.).} -\end{ncbnf} - -\begin{ncbnf} -\nontermdef{dot-dot}\br - \textnormal{The filename consisting solely of two period characters (..).} + \textnormal{non-empty sequence of characters other than \grammarterm{directory-separator} characters} \end{ncbnf} \begin{ncbnf} \nontermdef{directory-separator}\br - slash\br - slash directory-separator\br - preferred-separator\br - preferred-separator directory-separator + preferred-separator directory-separator\opt\br + fallback-separator directory-separator\opt \end{ncbnf} \begin{ncbnf} \nontermdef{preferred-separator}\br - \textnormal{An operating system dependent directory separator character. May be a synonym for \grammarterm{slash}.} + \textnormal{operating system dependent directory separator character} \end{ncbnf} \begin{ncbnf} -\nontermdef{slash}\br - \textnormal{The slash character (\tcode{/}).} +\nontermdef{fallback-separator}\br + \textnormal{\tcode{/}, if \grammarterm{preferred-separator} is not \tcode{/}} \end{ncbnf} \pnum -Multiple successive \grammarterm{directory-separator} characters are considered to +\begin{note} +Operating systems often place restrictions +on the characters that may be used in a \grammarterm{filename}. +For wide portability, users may wish to limit \grammarterm{filename} +characters to the POSIX Portable Filename Character Set: \\ +\tcode{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} \\ +\tcode{a b c d e f g h i j k l m n o p q r s t u v w x y z} \\ +\tcode{0 1 2 3 4 5 6 7 8 9 . _ -} +\end{note} + +\pnum +Except in a \grammarterm{root-name}, +multiple successive \grammarterm{directory-separator} characters are considered to be the same as one \grammarterm{directory-separator} character. \pnum -The filename \grammarterm{dot} is treated as a reference to the current directory. -The filename \grammarterm{dot-dot} is treated as a reference to the parent directory. +The filename \grammarterm{dot}~(\ref{fs.def.filename}) is treated as a reference to the current directory. +The filename \grammarterm{dot-dot}~(\ref{fs.def.filename}) is treated as a reference to the parent directory. What the filename \grammarterm{dot-dot} refers to relative to \grammarterm{root-directory} is \impldef{meaning of \grammarterm{dot-dot} in \grammarterm{root-directory}}. Specific filenames may have special meanings for a particular operating system. -\rSec3[path.cvt]{\tcode{path} conversions} +\pnum +A \grammarterm{root-name} identifies the +starting location for pathname resolution~(\ref{fs.def.pathres}). +If there are no operating system dependent \grammarterm{root-name}{s}, +at least one \impldefrootname{} \grammarterm{root-name} is required. +\begin{note} Many operating systems define a name +beginning with two \grammarterm{directory-separator} characters +as a \grammarterm{root-name} that identifies +network or other resource locations. +Some operating systems +define a single letter followed by a colon +as a drive specifier -- a \grammarterm{root-name} +identifying a specific device such as a disk drive. +\end{note} + +\pnum +If a \grammarterm{root-name} is otherwise ambiguous, +the possibility with the longest sequence of characters is chosen. +\begin{note} +On a POSIX-like operating system, it is impossible to have a +\grammarterm{root-name} and a \grammarterm{relative-path} +without an intervening \grammarterm{root-directory} element. +\end{note} + +\rSec3[fs.path.cvt]{\tcode{path} conversions} -\rSec4[path.fmt.cvt]{\tcode{path} argument format conversions} +\rSec4[fs.path.fmt.cvt]{\tcode{path} argument format conversions} \pnum \begin{note} The format conversions described in this section -are not applied on POSIX- or Windows-based operating systems +are not applied on POSIX-based operating systems because on these systems: \begin{itemize} \item The generic format is acceptable as a native path. @@ -10673,12 +10757,13 @@ \end{note} \pnum -Function arguments that take character sequences representing -paths may use the generic pathname format grammar~(\ref{path.generic}) or -the native pathname format~(\ref{fs.def.native}). If and only if such -arguments are in the generic format and the generic format is not acceptable to -the operating system as a native path, conversion to native format shall be -performed during the processing of the argument. +Several functions are defined to accept \term{detected-format} arguments, +which are character sequences. A detected-format argument represents a path +using either a pathname in the generic format~(\ref{fs.path.generic}) +or a pathname in the native format~(\ref{fs.def.native}). +Such an argument is taken to be in the generic format if and only if +it matches the generic format and is not acceptable to the operating system +as a native path. \pnum \begin{note} @@ -10688,20 +10773,59 @@ is required is permitted to distinguish between the formats. \end{note} +\pnum +Pathnames are converted as needed between the generic and native formats +in an operating-system-dependent manner. +Let \placeholder{G(n)} and \placeholder{N(g)} in a mathematical sense +be the implementation's functions that convert native-to-generic +and generic-to-native formats respectively. +If \placeholder{g=G(n)} for some \placeholder{n}, then \placeholder{G(N(g))=g}; +if \placeholder{n=N(g)} for some \placeholder{g}, then \placeholder{N(G(n))=n}. +\begin{note} Neither \placeholder{G} nor \placeholder{N} need be invertible. \end{note} + \pnum If the native format requires paths for regular files to be formatted differently from paths for directories, the path shall be treated as a directory path if its last element is a \grammarterm{directory-separator}, otherwise it shall be treated as a path to a regular file. -\rSec4[path.type.cvt]{\tcode{path} type and encoding conversions} +\pnum +\begin{note} +A path stores a native format pathname~(\ref{fs.path.native.obs}) +and acts as if it also stores a generic format pathname, +related as given below. +The implementation may generate the generic format pathname +based on the native format pathname (and possibly other information) +when requested. +\end{note} + +\pnum +When a path is constructed from or is assigned a single representation +separate from any path, the other representation is selected +by the appropriate conversion function (\placeholder{G} or \placeholder{N}). + +\pnum +When the (new) value \placeholder{p} of one representation of a path +is derived from the representation of that or another path, +a value \placeholder{q} is chosen for the other representation. +The value \placeholder{q} converts to \placeholder{p} +(by \placeholder{G} or \placeholder{N} as appropriate) +if any such value does so; +\placeholder{q} is otherwise unspecified. +\begin{note} +If \placeholder{q} is the result of converting any path at all, +it is the result of converting \placeholder{p}. +\end{note} + + +\rSec4[fs.path.type.cvt]{\tcode{path} type and encoding conversions} \pnum For member function arguments that take character sequences representing paths and for member functions returning strings, value type and encoding conversion is performed if the value type of the argument or return value differs from \tcode{path::value_type}. -For the argument or return value, the method of conversion and the encoding +For the argument or return value, the method of conversion and the encoding to be converted to is determined by its value type: \begin{itemize} @@ -10736,8 +10860,10 @@ \pnum If the encoding being converted to has no representation for source characters, the resulting converted characters, if any, are unspecified. +Implementations should not modify member function arguments +if already of type \tcode{path::value_type}. -\rSec3[path.req]{\tcode{path} requirements} +\rSec3[fs.path.req]{\tcode{path} requirements} \pnum In addition to the requirements~(\ref{fs.req}), @@ -10767,14 +10893,18 @@ \pnum Functions taking template parameters named \tcode{Source} shall not participate in overload resolution unless either +\begin{itemize} +\item \tcode{Source} is a specialization of -\tcode{basic_string} or \tcode{basic_string_view} or +\tcode{basic_string} or \tcode{basic_string_view}, or +\item the \grammarterm{qualified-id} \tcode{iterator_traits>::value_type} is valid and denotes a possibly \tcode{const} encoded character type~(\ref{temp.deduct}). +\end{itemize} \pnum \begin{note} -See path conversions~(\ref{path.cvt}) +See path conversions~(\ref{fs.path.cvt}) for how the value types above and their encodings convert to \tcode{path::value_type} and its encoding. \end{note} @@ -10783,9 +10913,9 @@ Arguments of type \tcode{Source} shall not be null pointers. -\rSec3[path.member]{\tcode{path} members} +\rSec3[fs.path.member]{\tcode{path} members} -\rSec4[path.construct]{\tcode{path} constructors} +\rSec4[fs.path.construct]{\tcode{path} constructors} \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} @@ -10809,45 +10939,50 @@ \begin{itemdescr} \pnum \effects -Constructs an object of class \tcode{path} with -\tcode{pathstring} having the original value of \tcode{p.pathstring}. +Constructs an object of class \tcode{path} +having the same pathname in the native and generic formats, respectively, +as the original value of \tcode{p}. In the second form, \tcode{p} is left in a valid but unspecified state. \end{itemdescr} \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} -path(string_type&& source); +path(string_type&& source, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs an object of class \tcode{path} with -\tcode{pathstring} having the original value of \tcode{source}. +Constructs an object of class \tcode{path} +for which the pathname in the detected-format of \tcode{source} +has the original value of \tcode{source}~(\ref{fs.path.fmt.cvt}), +converting format if required~(\ref{fs.path.fmt.cvt}). \tcode{source} is left in a valid but unspecified state. \end{itemdescr} \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} template - path(const Source& source); + path(const Source& source, format fmt = auto_format); template - path(InputIterator first, InputIterator last); + path(InputIterator first, InputIterator last, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{path}, storing the effective range of \tcode{source}~(\ref{path.req}) - or the range \range{first}{last} in \tcode{pathstring}, - converting format and encoding if required~(\ref{path.cvt}). +\effects Let \tcode{s} be the effective range of \tcode{source}~(\ref{fs.path.req}) +or the range \range{first}{last}, with the encoding converted if required~(\ref{fs.path.cvt}). +Finds the detected-format of \tcode{s}~(\ref{fs.path.fmt.cvt}) +and constructs an object of class \tcode{path} +for which the pathname in that format is \tcode{s}. \end{itemdescr} \indexlibrary{\idxcode{path}!constructor}% \begin{itemdecl} template - path(const Source& source, const locale& loc); + path(const Source& source, const locale& loc, format fmt = auto_format); template - path(InputIterator first, InputIterator last, const locale& loc); + path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} @@ -10857,21 +10992,26 @@ \tcode{char}. \pnum -\effects Constructs an object of class \tcode{path}, -storing the effective range of \tcode{source} -or the range \range{first}{last} in \tcode{pathstring}, -after converting format if required and after converting the encoding as +\effects Let \tcode{s} be the effective range of \tcode{source} +or the range \range{first}{last}, +after converting the encoding as follows: \begin{itemize} \item If \tcode{value_type} is \tcode{wchar_t}, converts to the native -wide encoding~(\ref{fs.def.native.encode}) using the \tcode{codecvt} +wide encoding~(\ref{fs.def.native.encode}) using the \tcode{codecvt<\brk{}wchar_t, char, mbstate_t>} facet of \tcode{loc}. \item Otherwise a conversion is performed using the \tcode{codecvt} facet of \tcode{loc}, and then a second conversion to the current narrow encoding. \end{itemize} + +\pnum +Finds the detected-format of \tcode{s}~(\ref{fs.path.fmt.cvt}) +and constructs an object of class \tcode{path} +for which the pathname in that format is \tcode{s}. + \begin{example} A string is to be read from a database that is encoded in ISO/IEC 8859-1, and used to create a directory: @@ -10887,7 +11027,7 @@ \tcode{latin1_string} to a wide character string in the native wide encoding~(\ref{fs.def.native.encode}). The resulting wide string is then converted to a narrow character -\tcode{pathstring} string in the current native narrow encoding. If the +pathname string in the current native narrow encoding. If the native wide encoding is UTF-16 or UTF-32, and the current native narrow encoding is UTF-8, all of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation, but for other native @@ -10895,13 +11035,13 @@ For Windows-based operating systems, the path is constructed by using \tcode{latin1_facet} to convert ISO/IEC 8859-1 encoded -\tcode{latin1_string} to a UTF-16 encoded wide character \tcode{pathstring} +\tcode{latin1_string} to a UTF-16 encoded wide character pathname string. All of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation. \end{example} \end{itemdescr} -\rSec4[path.assign]{\tcode{path} assignments} +\rSec4[fs.path.assign]{\tcode{path} assignments} \indexlibrarymember{operator=}{path}% \begin{itemdecl} @@ -10911,8 +11051,10 @@ \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{p} are the same -object, has no effect. Otherwise, modifies \tcode{pathstring} to have the -original value of \tcode{p.pathstring}. +object, has no effect. +Otherwise, +sets both respective pathnames of \tcode{*this} +to the respective pathnames of \tcode{p}. \pnum \returns \tcode{*this}. @@ -10926,9 +11068,10 @@ \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{p} are the same -object, has no effect. Otherwise, modifies \tcode{pathstring} to have the -original value of \tcode{p.pathstring}. \tcode{p} is left in a -valid but unspecified state. +object, has no effect. Otherwise, +sets both respective pathnames of \tcode{*this} +to the respective pathnames of \tcode{p}. +\tcode{p} is left in a valid but unspecified state. \begin{note} A valid implementation is \tcode{swap(p)}. \end{note} \pnum @@ -10944,7 +11087,8 @@ \begin{itemdescr} \pnum -\effects Modifies \tcode{pathstring} to have the original value of \tcode{source}. +\effects Sets the pathname in the detected-format of \tcode{source} +to the original value of \tcode{source}. \tcode{source} is left in a valid but unspecified state. \pnum @@ -10964,15 +11108,17 @@ \begin{itemdescr} \pnum -\effects Stores the effective range of \tcode{source} (\ref{path.req}) -or the range \range{first}{last} in \tcode{pathstring}, -converting format and encoding if required (\ref{path.cvt}). +\effects +Let \tcode{s} be the effective range of \tcode{source}~(\ref{fs.path.req}) +or the range \range{first}{last}, with the encoding converted if required~(\ref{fs.path.cvt}). +Finds the detected-format of \tcode{s}~(\ref{fs.path.fmt.cvt}) +and sets the pathname in that format to \tcode{s}. \pnum \returns \tcode{*this}. \end{itemdescr} -\rSec4[path.append]{\tcode{path} appends} +\rSec4[fs.path.append]{\tcode{path} appends} \pnum The append operations use \tcode{operator/=} to denote their semantic effect of appending @@ -10985,19 +11131,45 @@ \begin{itemdescr} \pnum -\requires \tcode{!p.has_root_name()}. +\effects If \tcode{p.is_absolute() || (p.has_root_name() \&\& p.root_name() != root_name())}, +then \tcode{operator=(p)}. \pnum -\effects Appends \tcode{path::preferred_separator} to \tcode{pathstring} unless: +Otherwise, modifies \tcode{*this} as if by these steps: \begin{itemize} -\item an added \grammarterm{directory-separator} - would be redundant, or -\item an added \grammarterm{directory-separator} would change a relative path into an absolute path - \begin{note} An empty path is relative.\end{note}, or -\item \tcode{p.empty()} is \tcode{true}, or -\item \tcode{*p.native().cbegin()} is a \grammarterm{directory-separator}. +\item If \tcode{p.has_root_directory()}, + then removes any root directory and relative path + from the generic format pathname. + Otherwise, + if \tcode{!has_root_directory() \&\& is_absolute()} is \tcode{true} + or if \tcode{has_filename()} is \tcode{true}, + then appends \tcode{path::preferred_separator} to the generic format pathname. +\item Then appends the native format pathname of \tcode{p}, + omitting any \grammarterm{root-name} from its generic format pathname, + to the native format pathname. \end{itemize} -Then appends \tcode{p.native()} to \tcode{pathstring}. + +\pnum +\begin{example} +Even if \tcode{//host} is interpreted as a \grammarterm{root-name}, +both of the paths \tcode{path("//host")/"foo"} and \tcode{path("//host/")/"foo"} +equal \tcode{"//host/foo"}. + +Expression examples: +\begin{codeblock} +// On POSIX, +path("foo") / ""; // yields \tcode{"foo/"} +path("foo") / "/bar"; // yields \tcode{"/bar"} +// On Windows, backslashes replace slashes in the above yields + +// On Windows, +path("foo") / "c:/bar"; // yields \tcode{"c:/bar"} +path("foo") / "c:"; // yields \tcode{"c:"} +path("c:") / ""; // yields \tcode{"c:"} +path("c:foo") / "/bar"; // yields \tcode{"c:/bar"} +path("c:foo") / "c:bar"; // yields \tcode{"c:foo/bar"} +\end{codeblock} +\end{example} \pnum \returns \tcode{*this}. @@ -11029,7 +11201,7 @@ \effects Equivalent to: \tcode{return operator/=(path(first, last));} \end{itemdescr} -\rSec4[path.concat]{\tcode{path} concatenation} +\rSec4[fs.path.concat]{\tcode{path} concatenation} \indexlibrarymember{operator+=}{path}% \indexlibrarymember{concat}{path}% @@ -11045,32 +11217,32 @@ path& operator+=(EcharT x); template path& concat(const Source& x); -template - path& concat(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{native() == prior_native + \textit{effective-argument}}, - where \tcode{prior_native} is \tcode{native()} prior to the call to \tcode{operator+=}, - and \tcode{\textit{effective-argument}} is: - \begin{itemize} -\item if \tcode{x} is present and is \tcode{const path\&}, - \tcode{x.native()}; otherwise, -\item if \tcode{source} is present, - the effective range of \tcode{source}~(\ref{path.req}); otherwise, -\item if \tcode{first} and \tcode{last} are present, - the range \range{first}{last}; otherwise, -\item \tcode{x}. -\end{itemize} -If the value type of \tcode{\textit{effective-argument}} would not be \tcode{path::value_type}, - the actual argument or argument range is first converted (\ref{path.type.cvt}) so that \tcode{\textit{effective-argument}} has value type \tcode{path::value_type}. +\effects Appends \tcode{path(x).native()} to the pathname in the native format. +\begin{note} +This directly manipulates the value of \tcode{native()} +and may not be portable between operating systems. +\end{note} \pnum \returns \tcode{*this}. \end{itemdescr} -\rSec4[path.modifiers]{\tcode{path} modifiers} +\indexlibrarymember{concat}{path}% +\begin{itemdecl} +template + path& concat(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{return *this += path(first, last)}. +\end{itemdescr} + +\rSec4[fs.path.modifiers]{\tcode{path} modifiers} \indexlibrarymember{clear}{path}% \begin{itemdecl} @@ -11090,6 +11262,7 @@ \begin{itemdescr} \pnum \effects Each \grammarterm{directory-separator} +of the pathname in the generic format is converted to \grammarterm{preferred-separator}. \pnum @@ -11103,8 +11276,8 @@ p.make_preferred(); std::cout << p << '\n'; \end{codeblock} -On an operating system where \grammarterm{preferred-separator} is the same as -\grammarterm{directory-separator}, the output is: +On an operating system where \grammarterm{preferred-separator} is a slash, +the output is: \begin{codeblock} "foo/bar" "foo/bar" @@ -11127,14 +11300,19 @@ \pnum \postconditions \tcode{!has_filename()}. +\pnum +\effects Remove the generic format pathname of \tcode{filename()} from the generic format pathname. + \pnum \returns \tcode{*this}. \pnum \begin{example} \begin{codeblock} -std::cout << path("/foo").remove_filename(); // outputs \tcode{"/"} -std::cout << path("/").remove_filename(); // outputs \tcode{""} +path("foo/bar").remove_filename(); // yields \tcode{"foo/"} +path("foo/").remove_filename(); // yields \tcode{"foo/"} +path("/foo").remove_filename(); // yields \tcode{"/"} +path("/").remove_filename(); // yields \tcode{"/"} \end{codeblock} \end{example} \end{itemdescr} @@ -11159,7 +11337,8 @@ \pnum \begin{example} \begin{codeblock} -std::cout << path("/").replace_filename("bar"); // outputs \tcode{"bar"} +path("/foo").replace_filename("bar"); // yields \tcode{"/bar"} on POSIX +path("/").replace_filename("bar"); // yields \tcode{"/bar"} on POSIX \end{codeblock} \end{example} \end{itemdescr} @@ -11171,14 +11350,15 @@ \begin{itemdescr} \pnum -\effects \tcode{pathstring} (the stored path) is modified as follows: +\effects \begin{itemize} -\item Any existing \tcode{extension()(}\ref{path.decompose}\tcode{)} is removed from the stored path, +\item Any existing \tcode{extension()(}\ref{fs.path.decompose}\tcode{)} is removed from the + pathname in the generic format, then \item If \tcode{replacement} is not empty and does not begin with a dot - character, a dot character is appended to the stored path, then + character, a dot character is appended to the pathname in the generic format, then \item - \tcode{replacement} is concatenated to the stored path. + \tcode{operator+=(replacement);}. \end{itemize} \pnum @@ -11192,14 +11372,13 @@ \begin{itemdescr} \pnum -\effects Swaps the contents of the two paths \tcode{pathstring} and -\tcode{rhs.pathstring}. +\effects Swaps the contents (in all formats) of the two paths. \pnum \complexity Constant time. \end{itemdescr} -\rSec4[path.native.obs]{\tcode{path} native format observers} +\rSec4[fs.path.native.obs]{\tcode{path} native format observers} \pnum The string returned by all native format observers is in the native pathname format~(\ref{fs.def.native}). @@ -11211,7 +11390,7 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring}. +\returns The pathname in the native format. \end{itemdescr} \indexlibrarymember{c_str}{path}% @@ -11221,7 +11400,7 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring.c_str()}. +\returns Equivalent to \tcode{native().c_str()}. \end{itemdescr} \indexlibrarymember{operator string_type}{path}% @@ -11231,7 +11410,7 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring}. +\returns \tcode{native()}. \pnum \begin{note} Conversion to \tcode{string_type} is provided so that an @@ -11249,12 +11428,12 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring}. +\returns \tcode{native()}. \pnum \remarks All memory allocation, including for the return value, shall be performed by \tcode{a}. Conversion, if any, is specified by -\ref{path.cvt}. +\ref{fs.path.cvt}. \end{itemdescr} \indexlibrarymember{string}{path}% @@ -11276,22 +11455,25 @@ \pnum \remarks Conversion, if any, is performed as specified -by \ref{path.cvt}. +by \ref{fs.path.cvt}. The encoding of the string returned by \tcode{u8string()} is always UTF-8. \end{itemdescr} -\rSec4[path.generic.obs]{\tcode{path} generic format observers} +\rSec4[fs.path.generic.obs]{\tcode{path} generic format observers} \pnum Generic format observer functions return strings formatted according to the -generic pathname format (\ref{path.generic}). -The forward slash (\tcode{'/'}) character is used as -the \grammarterm{directory-separator} character. +generic pathname format (\ref{fs.path.generic}). +A single slash (\tcode{'/'}) character is used as +the \grammarterm{directory-separator}. \pnum \begin{example} On an operating system that uses backslash as -its \grammarterm{preferred-separator}, \tcode{path("foo\textbackslash\textbackslash{}bar").generic_string()} +its \grammarterm{preferred-separator}, +\begin{codeblock} +path("foo\\bar").generic_string() +\end{codeblock} returns \tcode{"foo/bar"}. \end{example} \indexlibrarymember{generic_string}{path}% @@ -11304,13 +11486,12 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring}, reformatted according to the generic -pathname format (\ref{path.generic}). +\returns The pathname in the generic format. \pnum \remarks All memory allocation, including for the return value, shall be performed by \tcode{a}. Conversion, if any, is specified by -\ref{path.cvt}. +\ref{fs.path.cvt}. \end{itemdescr} \indexlibrarymember{generic_string}{path}% @@ -11328,16 +11509,15 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring}, reformatted according to the generic -pathname format~(\ref{path.generic}). +\returns The pathname in the generic format. \pnum -\remarks Conversion, if any, is specified by~\ref{path.cvt}. +\remarks Conversion, if any, is specified by~\ref{fs.path.cvt}. The encoding of the string returned by \tcode{generic_u8string()} is always UTF-8. \end{itemdescr} -\rSec4[path.compare]{\tcode{path} compare} +\rSec4[fs.path.compare]{\tcode{path} compare} \indexlibrarymember{compare}{path}% \begin{itemdecl} @@ -11385,7 +11565,7 @@ \returns \tcode{compare(path(s))}. \end{itemdescr} -\rSec4[path.decompose]{\tcode{path} decomposition} +\rSec4[fs.path.decompose]{\tcode{path} decomposition} \indexlibrarymember{root_name}{path}% \begin{itemdecl} @@ -11394,7 +11574,8 @@ \begin{itemdescr} \pnum -\returns \grammarterm{root-name}, if \tcode{pathstring} includes \grammarterm{root-name}, otherwise \tcode{path()}. +\returns \grammarterm{root-name}, if the pathname in the generic format +includes \grammarterm{root-name}, otherwise \tcode{path()}. \end{itemdescr} \indexlibrarymember{root_directory}{path}% @@ -11404,7 +11585,8 @@ \begin{itemdescr} \pnum -\returns \grammarterm{root-directory}, if \tcode{pathstring} includes \grammarterm{root-directory}, otherwise \tcode{path()}. +\returns \grammarterm{root-directory}, if the pathname in the generic format +includes \grammarterm{root-directory}, otherwise \tcode{path()}. \end{itemdescr} \indexlibrarymember{root_path}{path}% @@ -11424,7 +11606,8 @@ \begin{itemdescr} \pnum -\returns A \tcode{path} composed from \tcode{pathstring}, if \tcode{!empty()}, beginning +\returns A \tcode{path} composed from the pathname in the generic format, +if \tcode{!empty()}, beginning with the first \grammarterm{filename} after \grammarterm{root-path}. Otherwise, \tcode{path()}. \end{itemdescr} @@ -11435,10 +11618,10 @@ \begin{itemdescr} \pnum -\returns \tcode{(empty() || begin() == --end()) ? path() : \textit{pp}}, -where \tcode{\textit{pp}} is constructed as if by - starting with an empty \tcode{path} and successively applying \tcode{operator/=} for each element in the range - \range{begin()}{--end()}. +\returns \tcode{*this} if \tcode{!has_relative_path()}, +otherwise a path whose generic format pathname is +the longest prefix of the generic format pathname of \tcode{*this} +that produces one fewer element in its iteration. \end{itemdescr} \indexlibrarymember{filename}{path}% @@ -11448,15 +11631,18 @@ \begin{itemdescr} \pnum -\returns \tcode{empty() ? path() : *--end()}. +\returns \tcode{relative_path().empty() ? path() : *--end()}. \pnum \begin{example} \begin{codeblock} -std::cout << path("/foo/bar.txt").filename(); // outputs "bar.txt" -std::cout << path("/").filename(); // outputs "/" -std::cout << path(".").filename(); // outputs "." -std::cout << path("..").filename(); // outputs ".." +path("/foo/bar.txt").filename(); // yields \tcode{"bar.txt"} +path("/foo/bar").filename(); // yields \tcode{"bar"} +path("/foo/bar/").filename(); // yields \tcode{""} +path("/").filename(); // yields \tcode{""} +path("//host").filename(); // yields \tcode{""} +path(".").filename(); // yields \tcode{"."} +path("..").filename(); // yields \tcode{".."} \end{codeblock} \end{example} \end{itemdescr} @@ -11468,11 +11654,13 @@ \begin{itemdescr} \pnum -\returns if \tcode{filename()} contains a period but does not - consist solely of one or two periods, returns - the substring of \tcode{filename()} starting at its beginning and - ending with the character before the last period. Otherwise, - returns \tcode{filename()}. +\returns Let \tcode{f} be the generic format pathname of \tcode{filename()}. +Returns a path whose pathname in the generic format is +\begin{itemize} +\item \tcode{f}, if it contains no periods other than a leading period +or consists solely of one or two periods; +\item otherwise, the prefix of \tcode{f} ending before its last period. +\end{itemize} \pnum \begin{example} @@ -11495,31 +11683,34 @@ \begin{itemdescr} \pnum -\returns if \tcode{filename()} contains a period but does not - consist solely of one or two periods, returns - the substring of \tcode{filename()} starting at the rightmost period - and for the remainder of the path. Otherwise, returns an empty \tcode{path} object. - -\pnum -\remarks Implementations are permitted to define additional - behavior for file systems which append additional elements to extensions, such - as alternate data streams or partitioned dataset names. +\returns a path whose pathname in the generic format is +the suffix of \tcode{filename()} not included in \tcode{stem()}. \pnum \begin{example} \begin{codeblock} -std::cout << path("/foo/bar.txt").extension(); // outputs ".txt" +path("/foo/bar.txt").extension(); // yields \tcode{".txt"} and \tcode{stem()} is \tcode{"bar"} +path("/foo/bar").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{"bar"} +path("/foo/.profile").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{".profile"} +path(".bar").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{".bar"} +path("..bar").extension(); // yields \tcode{".bar"} and \tcode{stem()} is \tcode{"."} \end{codeblock} \end{example} \pnum \begin{note} The period is included in the return value so that it is - possible to distinguish between no extension and an empty extension. Also note - that for a path \tcode{p}, \tcode{p.stem()+p.extension() == p.filename()}. - \end{note} + possible to distinguish between no extension and an empty extension. +\end{note} + +\pnum +\begin{note} +On non-POSIX operating systems, for a path \tcode{p}, +it may not be the case that \tcode{p.stem() + p.extension() == p.filename()}, +even though the generic format pathnames are the same. +\end{note} \end{itemdescr} -\rSec4[path.query]{\tcode{path} query} +\rSec4[fs.path.query]{\tcode{path} query} \indexlibrarymember{empty}{path}% \begin{itemdecl} @@ -11528,7 +11719,7 @@ \begin{itemdescr} \pnum -\returns \tcode{pathstring.empty()}. +\returns \tcode{true} if the pathname in the generic format is empty, else \tcode{false}. \end{itemdescr} \indexlibrarymember{has_root_path}{path}% @@ -11618,7 +11809,7 @@ \begin{itemdescr} \pnum -\returns \tcode{true} if \tcode{pathstring} +\returns \tcode{true} if the pathname in the native format contains an absolute path (\ref{fs.def.absolute.path}), else \tcode{false}. \pnum @@ -11637,7 +11828,7 @@ \returns \tcode{!is_absolute()}. \end{itemdescr} -\rSec4[path.gen]{\tcode{path} generation} +\rSec4[fs.path.gen]{\tcode{path} generation} \indexlibrarymember{lexically_normal}{path}% \begin{itemdecl} @@ -11646,18 +11837,17 @@ \begin{itemdescr} \pnum -\returns \tcode{*this} in normal form~(\ref{fs.def.normal.form}). +\returns A path whose pathname in the generic format is +the normal form~(\ref{fs.def.normal.form}) of the pathname +in the generic format of \tcode{*this}. +\pnum \begin{example} \begin{codeblock} -assert(path("foo/./bar/..").lexically_normal() == "foo"); -assert(path("foo/.///bar/../").lexically_normal() == "foo/."); +assert(path("foo/./bar/..").lexically_normal() == "foo/"); +assert(path("foo/.///bar/../").lexically_normal() == "foo/"); \end{codeblock} The above assertions will succeed. -The second example ends with a current directory (\grammarterm{dot}) element -appended to support operating systems -that use different syntax for directory names and regular file names. - On Windows, the returned path's \grammarterm{directory-separator} characters will be backslashes rather than slashes, but that does not affect \tcode{path} equality. @@ -11677,6 +11867,10 @@ \pnum \effects +If \tcode{root_name() != base.root_name()} is \tcode{true} +or \tcode{is_absolute() != base.is_absolute()} is \tcode{true} +or \tcode{!has_root_directory() \&\& base.has_root_directory()} is \tcode{true}, +returns \tcode{path()}. Determines the first mismatched element of \tcode{*this} and \tcode{base} as if by: \begin{codeblock} @@ -11684,17 +11878,20 @@ \end{codeblock} Then, \begin{itemize} -\item if \tcode{a == begin()} and \tcode{b == base.begin()}, returns \tcode{path()}; otherwise \item if \tcode{a == end()} and \tcode{b == base.end()}, returns \tcode{path(".")}; otherwise +\item let \tcode{n} be the number of \grammarterm{filename} elements in \range{b}{base.end()} +that are not \grammarterm{dot} or \grammarterm{dot-dot} minus the number that are \grammarterm{dot-dot}. +If \tcode{n<0,} returns \tcode{path()}; otherwise \item returns an object of class \tcode{path} that is default-constructed, followed by \begin{itemize} \item application of \tcode{operator/=(path(".."))} - for each element in \range{b}{base.end()}, and then + \tcode{n} times, and then \item application of \tcode{operator/=} for each element in \range{a}{end()}. \end{itemize} \end{itemize} +\pnum \begin{example} \begin{codeblock} assert(path("/a/d").lexically_relative("/a/b/c") == "../../d"); @@ -11702,17 +11899,19 @@ assert(path("a/b/c").lexically_relative("a") == "b/c"); assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../.."); assert(path("a/b/c").lexically_relative("a/b/c") == "."); -assert(path("a/b").lexically_relative("c/d") == ""); +assert(path("a/b").lexically_relative("c/d") == "../../a/b"); \end{codeblock} The above assertions will succeed. On Windows, the returned path's \grammarterm{directory-separator} characters -will be backslashes rather than forward slashes, +will be backslashes rather than slashes, but that does not affect \tcode{path} equality. \end{example} +\pnum \begin{note} If symlink following semantics are desired, use the operational function \tcode{relative()}. \end{note} +\pnum \begin{note} If normalization~(\ref{fs.def.normal.form}) is needed to ensure consistent matching of elements, apply \tcode{lexically_normal()} to @@ -11729,21 +11928,23 @@ \returns If the value of \tcode{lexically_relative(base)} is not an empty path, return it. Otherwise return \tcode{*this}. +\pnum \begin{note} If symlink following semantics are desired, use the operational function \tcode{proximate()}. \end{note} +\pnum \begin{note} If normalization~(\ref{fs.def.normal.form}) is needed to ensure consistent matching of elements, apply \tcode{lexically_normal()} to \tcode{*this}, \tcode{base}, or both. \end{note} \end{itemdescr} -\rSec3[path.itr]{\tcode{path} iterators} +\rSec3[fs.path.itr]{\tcode{path} iterators} \indexlibrary{\idxcode{path}!\idxcode{iterator}}% \pnum -Path iterators iterate over the elements of \tcode{pathstring} -in the generic format~(\ref{path.generic}). +Path iterators iterate over the elements of the pathname +in the generic format~(\ref{fs.path.generic}). \pnum A \tcode{path::iterator} is a constant iterator satisfying all the @@ -11761,7 +11962,7 @@ invalidates all iterators referring to elements of that object. \pnum -For the elements of \tcode{pathstring} in the generic format, +For the elements of the pathname in the generic format, the forward traversal order is as follows: \begin{itemize} \item The \grammarterm{root-name} element, if present. @@ -11770,8 +11971,8 @@ The generic format is required to ensure lexicographical comparison works correctly. \end{note} \item Each successive \grammarterm{filename} element, if present. -\item \grammarterm{dot}, if one or more trailing non-root \grammarterm{slash} -characters are present. +\item An empty element, if a trailing non-root \grammarterm{directory-separator} +is present. \end{itemize} \pnum @@ -11798,7 +11999,7 @@ \returns The end iterator. \end{itemdescr} -\rSec3[path.non-member]{\tcode{path} non-member functions} +\rSec3[fs.path.nonmember]{\tcode{path} non-member functions} \indexlibrary{\idxcode{swap}!\idxcode{path}}% \begin{itemdecl} @@ -11908,7 +12109,7 @@ \effects Equivalent to: \tcode{return path(lhs) /= rhs;} \end{itemdescr} -\rSec4[path.io]{\tcode{path} inserter and extractor} +\rSec4[fs.path.io]{\tcode{path} inserter and extractor} \indexlibrarymember{operator<<}{path}% \begin{itemdecl} @@ -11947,7 +12148,7 @@ \returns \tcode{is}. \end{itemdescr} -\rSec4[path.factory]{\tcode{path} factory functions} +\rSec4[fs.path.factory]{\tcode{path} factory functions} \indexlibrary{\idxcode{u8path}}% \begin{itemdecl} @@ -11983,7 +12184,7 @@ \end{itemize} \pnum -\remarks Argument format conversion (\ref{path.fmt.cvt}) applies to the +\remarks Argument format conversion (\ref{fs.path.fmt.cvt}) applies to the arguments for these functions. How Unicode encoding conversions are performed is unspecified. @@ -12011,7 +12212,7 @@ \end{itemdescr} -\rSec2[class.filesystem_error]{Class \tcode{filesystem_error}} +\rSec2[fs.class.filesystem_error]{Class \tcode{filesystem_error}} \indexlibrary{\idxcode{filesystem_error}}% \begin{codeblock} @@ -12144,15 +12345,38 @@ \rSec2[fs.enum]{Enumerations} -\rSec3[enum.file_type]{Enum class \tcode{file_type}} +\rSec3[fs.enum.path.format]{Enum \tcode{path::format}} + +\pnum +This enum specifies constants used to identify the format of the character +sequence, with the meanings listed in Table~\ref{tab:enum.path.format}. + +\begin{floattable} +{Enum \tcode{path::format}}{tab:enum.path.format}{lp{4in}} +\topline +\lhdr{Name} & \rhdr{Meaning} \\\capsep +\tcode{native_format} & The native pathname format. \\\rowsep +\tcode{generic_format} & The generic pathname format. \\\rowsep +\tcode{auto_format} & + The interpretation of the format of the character sequence is + \impldef{interpretation of the path character sequence with format \tcode{path::auto_format}}. + The implementation may inspect the content of the character sequence to + determine the format. + \begin{note} + For POSIX-based systems, native and generic formats are equivalent + and the character sequence should always be interpreted in the same way. + \end{note} \\\rowsep +\end{floattable} + +\rSec3[fs.enum.file_type]{Enum class \tcode{file_type}} \indexlibrary{\idxcode{file_type}}% \pnum This enum class specifies constants used to identify file types, -with the meanings listed in Table~\ref{tab:enum.file_type}. +with the meanings listed in Table~\ref{tab:fs.enum.file_type}. \begin{floattable} -{Enum class \tcode{file_type}}{tab:enum.file_type} +{Enum class \tcode{file_type}}{tab:fs.enum.file_type} {lp{4.5in}} \topline \lhdr{Constant} & @@ -12185,20 +12409,18 @@ The file exists but the type could not be determined \\ \end{floattable} -\rSec3[enum.copy_options]{Enum class \tcode{copy_options}} +\rSec3[fs.enum.copy.opts]{Enum class \tcode{copy_options}} \indexlibrary{\idxcode{copy_options}}% \pnum The \tcode{enum class} type \tcode{copy_options} is a bitmask type~(\ref{bitmask.types}) that specifies bitmask constants used to control the semantics of -copy operations. The constants are specified in option groups with the meanings listed in Table~\ref{tab:enum.copy_options}. +copy operations. The constants are specified in option groups with the meanings listed in Table~\ref{tab:fs.enum.copy_options}. Constant \tcode{none} is shown in each option group for purposes of exposition; -implementations shall provide only a single definition. Calling a -library function with more than a single constant for an option -group results in undefined behavior. +implementations shall provide only a single definition. \begin{floattable} -{Enum class \tcode{copy_options}}{tab:enum.copy_options} +{Enum class \tcode{copy_options}}{tab:fs.enum.copy_options} {lp{4in}} \topline \ohdrx{2}{Option group controlling \tcode{copy_file} function effects for existing target files} \\ \rowsep @@ -12242,16 +12464,16 @@ Make hard links instead of copies of files. \\ \end{floattable} -\rSec3[enum.perms]{Enum class \tcode{perms}} +\rSec3[fs.enum.perms]{Enum class \tcode{perms}} \indexlibrary{\idxcode{perms}}% \pnum The \tcode{enum class} type \tcode{perms} is a bitmask type~(\ref{bitmask.types}) that specifies bitmask constants used to identify file -permissions, with the meanings listed in Table~\ref{tab:enum.perms}. +permissions, with the meanings listed in Table~\ref{tab:fs.enum.perms}. \begin{floattable} -{Enum class \tcode{perms}}{tab:enum.perms} +{Enum class \tcode{perms}}{tab:fs.enum.perms} {lrlp{3.2in}} \topline \lhdr{Name} & \chdr{Value} & \chdr{POSIX} & \rhdr{Definition or notes} \\ @@ -12299,28 +12521,49 @@ \tcode{unknown} & \tcode{0xFFFF} & & The permissions are not known, such as when a \tcode{file_status} object is created without specifying the permissions \\ \rowsep -\tcode{add_perms} & \tcode{0x10000} & & - \tcode{permissions()} shall bitwise \textit{or} the \tcode{perm} argument's permission bits to the - file's current permission bits. \\ \rowsep -\tcode{remove_perms} & \tcode{0x20000} & & - \tcode{permissions()} shall bitwise \textit{and} the complement of - \tcode{perm} argument's permission bits to the - file's current permission bits. \\ \rowsep -\tcode{symlink_nofollow} & - \tcode{0x40000} & & - \tcode{permissions()} shall change the permissions of symbolic links. \\ \rowsep \end{floattable} -\rSec3[enum.directory_options]{Enum class \tcode{directory_options}} +\rSec3[fs.enum.perm.opts]{Enum class \tcode{perm_options}} + +\indexlibrary{\idxcode{perm_options}}% +\pnum +The \tcode{enum class} type \tcode{perm_options} +is a bitmask type~(\ref{bitmask.types}) that specifies bitmask constants used to +control the semantics of permissions operations, +with the meanings listed in Table~\ref{tab:enum.perm_options}. +The bitmask constants are bitmask elements. +In Table~\ref{tab:enum.perm_options} \tcode{perm} denotes a value of type \tcode{perms} +passed to \tcode{permissions}. + +\begin{floattable} +{Enum class \tcode{perm_options}}{tab:enum.perm_options}{x{.15\hsize}x{.70\hsize}} +\topline +\lhdr{Name} & + \rhdr{Meaning} \\ \capsep +\tcode{replace} & + \tcode{permissions} shall replace the file's permission bits with \tcode{perm} \\ \rowsep +\tcode{add} & + \tcode{permissions} shall replace the file's permission bits with + the bitwise OR of \tcode{perm} and the file's current permission bits. \\ \rowsep +\tcode{remove} & + \tcode{permissions} shall replace the file's permission bits with + the bitwise AND of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep +\tcode{nofollow} & + \tcode{permissions} shall change the permissions of a symbolic link itself + rather than the permissions of the file the link resolves to. \\ +\end{floattable} + + +\rSec3[fs.enum.dir.opts]{Enum class \tcode{directory_options}} \indexlibrary{\idxcode{directory_options}}% \pnum The \tcode{enum class} type \tcode{directory_options} is a bitmask type~(\ref{bitmask.types}) that specifies bitmask constants used to identify - directory traversal options, with the meanings listed in Table~\ref{tab:enum.directory_options}. + directory traversal options, with the meanings listed in Table~\ref{tab:fs.enum.directory_options}. \begin{floattable} -{Enum class \tcode{directory_options}}{tab:enum.directory_options} +{Enum class \tcode{directory_options}}{tab:fs.enum.directory_options} {lp{3in}} \topline \lhdr{Name} & @@ -12334,29 +12577,30 @@ Skip directories that would otherwise result in permission denied. \\ \end{floattable} -\rSec2[class.file_status]{Class \tcode{file_status}} +\rSec2[fs.class.file_status]{Class \tcode{file_status}} \indexlibrary{\idxcode{file_status}}% \begin{codeblock} namespace std::filesystem { class file_status { public: - // \ref{file_status.cons}, constructors and destructor - explicit file_status(file_type ft = file_type::none, + // \ref{fs.file_status.cons}, constructors and destructor + file_status() noexcept : file_status(file_type::none) {} + explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; file_status(const file_status&) noexcept = default; file_status(file_status&&) noexcept = default; - ~file_status(); + ~file_status(); // assignments: file_status& operator=(const file_status&) noexcept = default; file_status& operator=(file_status&&) noexcept = default; - // \ref{file_status.mods}, modifiers + // \ref{fs.file_status.mods}, modifiers void type(file_type ft) noexcept; void permissions(perms prms) noexcept; - // \ref{file_status.obs}, observers + // \ref{fs.file_status.obs}, observers file_type type() const noexcept; perms permissions() const noexcept; }; @@ -12366,17 +12610,7 @@ \pnum An object of type \tcode{file_status} stores information about the type and permissions of a file. -\rSec3[file_status.cons]{\tcode{file_status} constructors} - -\indexlibrary{\idxcode{file_status}!constructor}% -\begin{itemdecl} -explicit file_status() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\postconditions \tcode{type() == file_type::none} and \tcode{permissions() == perms::unknown}. -\end{itemdescr} +\rSec3[fs.file_status.cons]{\tcode{file_status} constructors} \indexlibrary{\idxcode{file_status}!constructor}% \begin{itemdecl} @@ -12388,7 +12622,7 @@ \postconditions \tcode{type() == ft} and \tcode{permissions() == prms}. \end{itemdescr} -\rSec3[file_status.obs]{\tcode{file_status} observers} +\rSec3[fs.file_status.obs]{\tcode{file_status} observers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -12412,7 +12646,7 @@ \tcode{operator=}, or \tcode{permissions(perms)} function. \end{itemdescr} -\rSec3[file_status.mods]{\tcode{file_status} modifiers} +\rSec3[fs.file_status.mods]{\tcode{file_status} modifiers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} @@ -12434,35 +12668,64 @@ \postconditions \tcode{permissions() == prms}. \end{itemdescr} -\rSec2[class.directory_entry]{Class \tcode{directory_entry}} +\rSec2[fs.class.directory_entry]{Class \tcode{directory_entry}} \indexlibrary{\idxcode{directory_entry}}% \begin{codeblock} namespace std::filesystem { class directory_entry { public: - // \ref{directory_entry.cons}, constructors and destructor - explicit directory_entry(const path& p); + // \ref{fs.dir.entry.cons}, constructors and destructor directory_entry() noexcept = default; directory_entry(const directory_entry&) = default; directory_entry(directory_entry&&) noexcept = default; - ~directory_entry(); + explicit directory_entry(const path& p); + directory_entry(const path& p, error_code& ec); + ~directory_entry(); // assignments: directory_entry& operator=(const directory_entry&) = default; directory_entry& operator=(directory_entry&&) noexcept = default; - // \ref{directory_entry.mods}, modifiers + // \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 refresh(); + void refresh(error_code& ec) noexcept; - // \ref{directory_entry.obs}, observers - const path& path() const noexcept; + // \ref{fs.dir.entry.obs}, observers + const path& path() const noexcept; operator const path&() const noexcept; - file_status status() const; - file_status status(error_code& ec) const noexcept; - file_status symlink_status() const; - file_status symlink_status(error_code& ec) const noexcept; + bool exists() const; + bool exists(error_code& ec) const noexcept; + bool is_block_file() const; + bool is_block_file(error_code& ec) const noexcept; + bool is_character_file() const; + bool is_character_file(error_code& ec) const noexcept; + bool is_directory() const; + bool is_directory(error_code& ec) const noexcept; + bool is_fifo() const; + bool is_fifo(error_code& ec) const noexcept; + bool is_other() const; + bool is_other(error_code& ec) const noexcept; + bool is_regular_file() const; + bool is_regular_file(error_code& ec) const noexcept; + bool is_socket() const; + bool is_socket(error_code& ec) const noexcept; + bool is_symlink() const; + bool is_symlink(error_code& ec) const noexcept; + uintmax_t file_size() const; + uintmax_t file_size(error_code& ec) const noexcept; + uintmax_t hard_link_count() const; + uintmax_t hard_link_count(error_code& ec) const noexcept; + file_time_type last_write_time() const; + file_time_type last_write_time(error_code& ec) const noexcept; + file_status status() const; + file_status status(error_code& ec) const noexcept; + file_status symlink_status() const; + file_status symlink_status(error_code& ec) const noexcept; bool operator< (const directory_entry& rhs) const noexcept; bool operator==(const directory_entry& rhs) const noexcept; @@ -12472,53 +12735,151 @@ bool operator>=(const directory_entry& rhs) const noexcept; private: - path pathobject; // \expos + path pathobject; // \expos + friend class directory_iterator; // \expos }; } \end{codeblock} \pnum -A \tcode{directory_entry} object stores a \tcode{path} object. +\indextext{file attributes}% +A \tcode{directory_entry} object stores a \tcode{path} object +and may store additional objects for file attributes +such as hard link count, status, symlink status, file size, and last write time. + +\pnum +Implementations are encouraged to store such additional file attributes +during directory iteration if their values are available +and storing the values would allow the implementation to eliminate file system accesses +by \tcode{directory_entry} observer functions~(\ref{fs.op.funcs}). +Such stored file attribute values are said to be \defnx{cached}{file attributes!cached}. + +\pnum +\begin{note} +For purposes of exposition, +class \tcode{directory_iterator}~(\ref{fs.class.directory_iterator}) +is shown above as a friend of class \tcode{directory_entry}. +Friendship allows the \tcode{directory_iterator} implementation to cache +already available attribute values +directly into a \tcode{directory_entry} object +without the cost of an unneeded call to \tcode{refresh()}. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +using namespace std::filesystem; -\rSec3[directory_entry.cons]{\tcode{directory_entry} constructors} +// use possibly cached last write time to minimize disk accesses +for (auto&& x : directory_iterator(".")) +{ + std::cout << x.path() << " " << x.last_write_time() << std::endl; +} + +// call \tcode{refresh()} to refresh a stale cache +for (auto&& x : directory_iterator(".")) +{ + lengthy_function(x.path()); // cache becomes stale + x.refresh(); + std::cout << x.path() << " " << x.last_write_time() << std::endl; +} +\end{codeblock} +On implementations that do not cache the last write time, +both loops will result in a potentially expensive call +to the \tcode{std::filesystem::last_write_time} function. +% +On implementations that do cache the last write time, +the first loop will use the cached value and so +will not result in a potentially expensive call +to the \tcode{std::filesystem::last_write_time} function. +% +The code is portable to any implementation, +regardless of whether or not it employs caching. +\end{example} + +\rSec3[fs.dir.entry.cons]{\tcode{directory_entry} constructors} \indexlibrary{\idxcode{directory_entry}!constructor}% \begin{itemdecl} explicit directory_entry(const path& p); +directory_entry(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{directory_entry}. +\effects Constructs an object of type \tcode{directory_entry}, +then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. + +\pnum +\postconditions \tcode{path() == p} if no error occurs, +otherwise \tcode{path() == std::filesystem::path()}. \pnum -\postconditions \tcode{path() == p}. +\throws As specified in~\ref{fs.err.report}. \end{itemdescr} -\rSec3[directory_entry.mods]{\tcode{directory_entry} modifiers} +\rSec3[fs.dir.entry.mods]{\tcode{directory_entry} modifiers} \indexlibrarymember{assign}{directory_entry}% \begin{itemdecl} void assign(const path& p); +void assign(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{path() == p}. +\effects Equivalent to \tcode{pathobject = p}, +then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. +If an error occurs, the values of any cached attributes are unspecified. + +\pnum +\throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{replace_filename}{directory_entry}% \begin{itemdecl} void replace_filename(const path& p); +void replace_filename(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{path() == x.parent_path() / p} where - \tcode{x} is the value of \tcode{path()} before the function is - called. +\effects Equivalent to \tcode{pathobject.replace_filename(p)}, +then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. +If an error occurs, the values of any cached attributes are unspecified. + +\throws As specified in~\ref{fs.err.report}. \end{itemdescr} -\rSec3[directory_entry.obs]{\tcode{directory_entry} observers} +\indexlibrarymember{refresh}{directory_entry}% +\begin{itemdecl} +void refresh(); +void refresh(error_code& ec) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Stores the current values of any cached attributes of the file \tcode{p} resolves to. +If an error occurs, an error is reported~(\ref{fs.err.report}) +and the values of any cached attributes are unspecified. + +\pnum +\throws As specified in~\ref{fs.err.report}. + +\pnum +\begin{note} +Implementations of \tcode{directory_iterator}~(\ref{fs.class.directory_iterator}) +are prohibited from directly or indirectly calling the \tcode{refresh} function +since it must access the external file system, +and the objective of caching is to avoid unnecessary file system accesses. +\end{note} +\end{itemdescr} + +\rSec3[fs.dir.entry.obs]{\tcode{directory_entry} observers} + +\pnum +Unqualified function names in the \returns elements of the +\tcode{directory_entry} observers described below refer to members of the +\tcode{std::filesystem} namespace. \indexlibrarymember{path}{directory_entry}% \indexlibrarymember{operator const path\&}{directory_entry}% @@ -12532,6 +12893,177 @@ \returns \tcode{pathobject}. \end{itemdescr} +\indexlibrarymember{exists}{directory_entry}% +\begin{itemdecl} +bool exists() const; +bool exists(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{exists(this->status())} or \tcode{exists(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_block_file}{directory_entry}% +\begin{itemdecl} +bool is_block_file() const; +bool is_block_file(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_block_file(this->status())} or \tcode{is_block_file(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_character_file}{directory_entry}% +\begin{itemdecl} +bool is_character_file() const; +bool is_character_file(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_character_file(this->status())} or \tcode{is_character_file(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_directory}{directory_entry}% +\begin{itemdecl} +bool is_directory() const; +bool is_directory(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_directory(this->status())} or \tcode{is_directory(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_fifo}{directory_entry}% +\begin{itemdecl} +bool is_fifo() const; +bool is_fifo(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_fifo(this->status())} or \tcode{is_fifo(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_other}{directory_entry}% +\begin{itemdecl} +bool is_other() const; +bool is_other(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_other(this->status())} or \tcode{is_other(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_regular_file}{directory_entry}% +\begin{itemdecl} +bool is_regular_file() const; +bool is_regular_file(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_regular_file(this->status())} or \tcode{is_regular_file(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_socket}{directory_entry}% +\begin{itemdecl} +bool is_socket() const; +bool is_socket(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_socket(this->status())} or \tcode{is_socket(this->status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{is_symlink}{directory_entry}% +\begin{itemdecl} +bool is_symlink() const; +bool is_symlink(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{is_symlink(this->symlink_status())} or \tcode{is_symlink(this->symlink_status(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{file_size}{directory_entry}% +\begin{itemdecl} +uintmax_t file_size() const; +uintmax_t file_size(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns If cached, the file size attribute value. +Otherwise, \tcode{file_size(path())} or \tcode{file_size(path(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{hard_link_count}{directory_entry}% +\begin{itemdecl} +uintmax_t hard_link_count() const; +uintmax_t hard_link_count(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns If cached, the hard link count attribute value. +Otherwise, \tcode{hard_link_count(path())} or \tcode{hard_link_count(path(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + +\indexlibrarymember{last_write_time}{directory_entry}% +\begin{itemdecl} +file_time_type last_write_time() const; +file_time_type last_write_time(error_code& ec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns If cached, the last write time attribute value. +Otherwise, \tcode{last_write_time(path())} or \tcode{last_write_time(path(), ec)}, respectively. + +\pnum +\throws As specified in~\ref{fs.err.report}. +\end{itemdescr} + \indexlibrarymember{status}{directory_entry}% \begin{itemdecl} file_status status() const; @@ -12540,7 +13072,8 @@ \begin{itemdescr} \pnum -\returns \tcode{status(path())} or \tcode{status(path(), ec)}, respectively. +\returns If cached, the status attribute value. +Otherwise, \tcode{status(path())} or \tcode{status(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. @@ -12554,7 +13087,8 @@ \begin{itemdescr} \pnum -\returns \tcode{symlink_status(path())} or \tcode{symlink_status(path(), ec)}, respectively. +\returns If cached, the symlink status attribute value. +Otherwise, \tcode{symlink_status(path())} or \tcode{symlink_status(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. @@ -12620,15 +13154,17 @@ \returns \tcode{pathobject >= rhs.pathobject}. \end{itemdescr} -\rSec2[class.directory_iterator]{Class \tcode{directory_iterator}} +\rSec2[fs.class.directory_iterator]{Class \tcode{directory_iterator}} \indexlibrary{\idxcode{directory_iterator}}% \pnum An object of type \tcode{directory_iterator} provides an iterator for a -sequence of \tcode{directory_entry} elements representing the files in a -directory. +sequence of \tcode{directory_entry} elements representing the +path and any cached attribute values~(\ref{fs.class.directory_entry}) +for each file in a directory +or in an \impldef{type of a directory-like file} directory-like file type. \begin{note} For iteration into sub-directories, see class \tcode{recursive_directory_iterator} -(\ref{class.rec.dir.itr}). \end{note} +(\ref{fs.class.rec.dir.itr}). \end{note} \begin{codeblock} namespace std::filesystem { @@ -12640,7 +13176,7 @@ using pointer = const directory_entry*; using reference = const directory_entry&; - // \ref{directory_iterator.members}, member functions + // \ref{fs.dir.itr.members}, member functions directory_iterator() noexcept; explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); @@ -12649,7 +13185,7 @@ error_code& ec) noexcept; directory_iterator(const directory_iterator& rhs); directory_iterator(directory_iterator&& rhs) noexcept; - ~directory_iterator(); + ~directory_iterator(); directory_iterator& operator=(const directory_iterator& rhs); directory_iterator& operator=(directory_iterator&& rhs) noexcept; @@ -12695,6 +13231,18 @@ The order of directory entries obtained by dereferencing successive increments of a \tcode{directory_iterator} is unspecified. +\pnum +Constructors and non-const \tcode{directory_iterator} member functions +store the values of any cached attributes~(\ref{fs.class.directory_entry}) +in the \tcode{directory_entry} element returned by \tcode{operator*()}. +\tcode{directory_iterator} member functions shall not directly or indirectly call +any \tcode{directory_entry} \tcode{refresh} function. +\begin{note} +The exact mechanism for storing cached attribute values is not exposed to users. +For exposition, class \tcode{directory_iterator} is shown in \ref{fs.class.directory_entry} +as a friend of class \tcode{directory_entry}. +\end{note} + \pnum \begin{note} Programs performing directory iteration may wish to test if the @@ -12713,7 +13261,7 @@ POSIX \tcode{readdir_r}. \end{note} -\rSec3[directory_iterator.members]{\tcode{directory_iterator} members} +\rSec3[fs.dir.itr.members]{\tcode{directory_iterator} members} \indexlibrary{\idxcode{directory_iterator}!constructor}% \begin{itemdecl} @@ -12806,7 +13354,7 @@ \end{itemdescr} -\rSec3[directory_iterator.nonmembers]{\tcode{directory_iterator} non-member functions} +\rSec3[fs.dir.itr.nonmembers]{\tcode{directory_iterator} non-member functions} \pnum These functions enable range access for \tcode{directory_iterator}. @@ -12831,13 +13379,14 @@ \returns \tcode{directory_iterator()}. \end{itemdescr} -\rSec2[class.rec.dir.itr]{Class \tcode{recursive_directory_iterator}} +\rSec2[fs.class.rec.dir.itr]{Class \tcode{recursive_directory_iterator}} \indexlibrary{\idxcode{recursive_directory_iterator}}% \pnum An object of type \tcode{recursive_directory_iterator} provides an iterator for a sequence of \tcode{directory_entry} elements representing the files in a -directory and its sub-directories. +directory or in an \impldef{type of a directory-like file} directory-like file +type, and its sub-directories. \begin{codeblock} namespace std::filesystem { @@ -12849,7 +13398,7 @@ using pointer = const directory_entry*; using reference = const directory_entry&; - // \ref{rec.dir.itr.members}, constructors and destructor + // \ref{fs.rec.dir.itr.members}, constructors and destructor recursive_directory_iterator() noexcept; explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); @@ -12858,9 +13407,9 @@ recursive_directory_iterator(const path& p, error_code& ec) noexcept; recursive_directory_iterator(const recursive_directory_iterator& rhs); recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; - ~recursive_directory_iterator(); + ~recursive_directory_iterator(); - // \ref{rec.dir.itr.members}, observers + // \ref{fs.rec.dir.itr.members}, observers directory_options options() const; int depth() const; bool recursion_pending() const; @@ -12868,7 +13417,7 @@ const directory_entry& operator*() const; const directory_entry* operator->() const; - // \ref{rec.dir.itr.members}, modifiers + // \ref{fs.rec.dir.itr.members}, modifiers recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); recursive_directory_iterator& @@ -12899,7 +13448,7 @@ \begin{note} If the directory structure being iterated over contains cycles then the end iterator may be unreachable. \end{note} -\rSec3[rec.dir.itr.members]{\tcode{recursive_directory_iterator} members} +\rSec3[fs.rec.dir.itr.members]{\tcode{recursive_directory_iterator} members} \indexlibrary{\idxcode{recursive_directory_iterator}!constructor}% \begin{itemdecl} @@ -12981,7 +13530,7 @@ \pnum \postconditions \tcode{options()}, \tcode{depth()}, - and \tcode{recursion_pending()} return the values that + and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. \end{itemdescr} @@ -13020,7 +13569,7 @@ \pnum \postconditions \tcode{options()}, \tcode{depth()}, -and \tcode{recursion_pending()} return the values that \tcode{rhs.options()}, +and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. \pnum @@ -13034,8 +13583,9 @@ \begin{itemdescr} \pnum -\returns The value of the constructor \tcode{options} argument, -if present, otherwise \tcode{directory_options::none}. +\returns The value of the argument passed to the constructor for the +\tcode{options} parameter, if present, otherwise +\tcode{directory_options::none}. \pnum \throws Nothing. @@ -13085,7 +13635,7 @@ except that: \begin{itemize} -\item If there are no more entries at the current depth, then if \tcode{depth()!= 0} +\item If there are no more entries at the current depth, then if \tcode{depth() != 0} iteration over the parent directory resumes; otherwise \tcode{*this = recursive_directory_iterator()}. \item Otherwise if @@ -13141,7 +13691,7 @@ unwanted recursion into a directory. \end{note} \end{itemdescr} -\rSec3[rec.dir.itr.nonmembers]{\tcode{recursive_directory_iterator} non-member functions} +\rSec3[fs.rec.dir.itr.nonmembers]{\tcode{recursive_directory_iterator} non-member functions} \pnum These functions enable use of \tcode{recursive_directory_iterator} @@ -13183,39 +13733,48 @@ \indexlibrary{\idxcode{absolute}}% \begin{itemdecl} -path absolute(const path& p, const path& base = current_path()); +path absolute(const path& p); +path absolute(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum -\returns An absolute path~(\ref{fs.def.absolute.path}) composed according to Table~\ref{tab:absolute.path}. - -\begin{lib2dtab2base} -{\tcode{absolute(const path\&, const path\&)} return value}{tab:absolute.path} -{\tcode{p.has_root_directory()}} -{\tcode{!p.has_root_directory()}} -{1.0in}{2.2in}{2.4in} +\effects Composes an absolute path referencing the same file system location +as \tcode{p} according to the operating system~(\ref{fs.conform.os}). -\rowhdr{\tcode{p.has_root_name()}} & -\tcode{p} & -\parbox{2.4in}{ -\tcode{p.root_name()} \\ -\tcode{/ absolute(base).root_directory()} \\ -\tcode{/ absolute(base).relative_path()} \\ -\tcode{/ p.relative_path()} -} -\\ \rowsep -\rowhdr{\tcode{!p.has_root_name()}} & -\tcode{absolute(base).root_name() / p} & -\tcode{absolute(base) / p} -\\ -\end{lib2dtab2base} +\pnum +\returns The composed path. +The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum -\begin{note} For the returned path, \tcode{rp}, \tcode{rp.is_absolute()} is \tcode{true}. \end{note} +\begin{note} +For the returned path, \tcode{rp}, \tcode{rp.is_absolute()} is \tcode{true} +unless an error occurs. +\end{note} \pnum \throws As specified in~\ref{fs.err.report}. + +\pnum +\begin{note} +To resolve symlinks, +or perform other sanitization which might require queries to secondary storage, +such as hard disks, consider \tcode{canonical}~(\ref{fs.op.canonical}). +\end{note} + +\pnum +\begin{note} +Implementations are strongly encouraged to not query secondary storage, +and not consider \tcode{!exists(p)} an error. +\end{note} + +\pnum +\begin{example} +For POSIX-based operating systems, +\tcode{absolute(p)} is simply \tcode{current_path()/p}. +For Windows-based operating systems, +\tcode{absolute} might have the same semantics as \tcode{GetFullPathNameW}. +\end{example} \end{itemdescr} \rSec3[fs.op.canonical]{Canonical} @@ -13230,8 +13789,8 @@ \begin{itemdescr} \pnum \effects Converts \tcode{p}, which must exist, to an absolute -path that has no symbolic link, \tcode{"."}, -or \tcode{".."} elements. +path that has no symbolic link, \grammarterm{dot}, or \grammarterm{dot-dot} elements +in its pathname in the generic format. \pnum \returns A path that refers to @@ -13251,14 +13810,23 @@ \indexlibrary{\idxcode{copy}!\idxcode{path}}% \begin{itemdecl} void copy(const path& from, const path& to); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to +\tcode{copy(from, to, copy_options::none)}. +\end{itemdescr} + +\indexlibrary{\idxcode{copy}!\idxcode{path}}% +\begin{itemdecl} void copy(const path& from, const path& to, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to -\tcode{copy(from, to, copy_options::none)} or -\tcode{copy(from, to, copy_options::none, ec)}, respectively. +\tcode{copy(from, to, copy_options::none, ec)}. \end{itemdescr} \indexlibrary{\idxcode{copy}!\idxcode{path}}% @@ -13270,8 +13838,8 @@ \begin{itemdescr} \pnum -\requires At most one constant from each option group (\ref{enum.copy_options}) - is present in \tcode{options}. +\requires At most one element from each option group (\ref{fs.enum.copy.opts}) + is set in \tcode{options}. \pnum \effects @@ -13294,7 +13862,12 @@ Effects are then as follows: \begin{itemize} \item -An error is reported as specified in~\ref{fs.err.report} if: +If \tcode{f.type()} or \tcode{t.type()} is an implementation-defined +file type~(\ref{fs.enum.file_type}), then the effects are +\impldef{effect of \tcode{filesystem::copy}}. + +\item +Otherwise, an error is reported as specified in~\ref{fs.err.report} if: \begin{itemize} \item \tcode{!exists(f)}, or \item \tcode{equivalent(from, to)}, or @@ -13320,11 +13893,11 @@ Otherwise, if \tcode{is_regular_file(f)}, then: \begin{itemize} \item If \tcode{(options \& copy_options::directories_only) != copy_options::none}, then return. -\item Otherwise if \tcode{(options \& copy_options::create_symlinks) != copy_options::none}, then create a symbolic link to the +\item Otherwise, if \tcode{(options \& copy_options::create_symlinks) \: != copy_options::none}, then create a symbolic link to the source file. -\item Otherwise if \tcode{(options \& copy_options::create_hard_links) != copy_options::none}, +\item Otherwise, if \tcode{(options \& copy_options::create_hard_links) != copy_options::none}, then create a hard link to the source file. -\item Otherwise if \tcode{is_directory(t)}, then \tcode{copy_file(from, to/from.filename(), options)}. +\item Otherwise, if \tcode{is_directory(t)}, then \tcode{copy_file(from, to/from.filename(), options)}. \item Otherwise, \tcode{copy_file(from, to, options)}. \end{itemize} @@ -13339,10 +13912,9 @@ \begin{itemize} \item If \tcode{!exists(t)}, then \tcode{create_directory(to, from)}. \item Then, iterate over the files in \tcode{from}, as if by -\tcode{for (const directory_entry\& x : directory_iterator(from))}, and -for each iteration \begin{codeblock} -copy(x.path(), to/x.path().filename(), options | copy_options::@\unspec@) +for (const directory_entry& x : directory_iterator(from)) + copy(x.path(), to/x.path().filename(), options | copy_options::@\unspec@) \end{codeblock} \end{itemize} @@ -13427,8 +13999,8 @@ \begin{itemdescr} \pnum -\requires At most one constant from each \tcode{copy_options} - option group (\ref{enum.copy_options}) is present +\requires At most one element from each + option group (\ref{fs.enum.copy.opts}) is set in \tcode{options}. \pnum @@ -13441,7 +14013,12 @@ \item \tcode{!is_regular_file(from)}, or \item \tcode{exists(to)} and \tcode{!is_regular_file(to)}, or \item \tcode{exists(to)} and \tcode{equivalent(from, to)}, or -\item \tcode{exists(to)} and \tcode{(options \& (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none}. +\item \tcode{exists(to)} and +\begin{codeblock} +(options & (copy_options::skip_existing | + copy_options::overwrite_existing | + copy_options::update_existing)) == copy_options::none +\end{codeblock} \end{itemize} \item @@ -13449,8 +14026,8 @@ resolves to, to the file \tcode{to} resolves to, if: \begin{itemize} \item \tcode{!exists(to)}, or -\item \tcode{exists(to)} and \tcode{(options \& copy_options::overwrite_existing) != copy_options::none}, or -\item \tcode{exists(to)} and \tcode{(options \& copy_options::update_existing) != copy_options::none} and \tcode{from} +\item \tcode{(options \& copy_options::overwrite_existing) != copy_options::none}, or +\item \tcode{(options \& copy_options::update_existing) \: \: != copy_options::none} and \tcode{from} is more recent than \tcode{to}, determined as if by use of the \tcode{last_write_time} function~(\ref{fs.op.last_write_time}). \end{itemize} @@ -13484,8 +14061,8 @@ \effects Equivalent to \tcode{\textit{function}(read_symlink(existing_symlink), new_symlink)} or\\ \tcode{\textit{function}(read_symlink(existing_symlink, ec), new_symlink, ec)}, respectively, - where \tcode{\textit{function}} is \tcode{create_symlink} or - \tcode{create_directory_symlink}, as appropriate. + where in each case \tcode{\textit{function}} is \tcode{create_symlink} or + \tcode{create_directory_symlink} as appropriate. \pnum \throws As specified in~\ref{fs.err.report}. @@ -13681,6 +14258,7 @@ \begin{itemdescr} \pnum \returns The absolute path of the current working directory, + whose pathname in the native format is obtained as if by POSIX \tcode{getcwd()}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. @@ -13805,13 +14383,19 @@ \begin{itemdescr} \pnum -\returns If \tcode{!exists(p) || !is_regular_file(p)} - an error is reported~(\ref{fs.err.report}). Otherwise, the size in bytes of the file +\returns +\begin{itemize} +\item + If \tcode{!exists(p)} an error is reported~(\ref{fs.err.report}). +\item + Otherwise, 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()}. - The signature - with argument \tcode{ec} returns \tcode{static_cast(-1)} - if an error occurs. +\item + Otherwise, the result is \impldef{result of \tcode{filesystem::file_size}}. +\end{itemize} +The signature with argument \tcode{ec} returns \tcode{static_cast(-1)} +if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. @@ -13887,7 +14471,7 @@ \pnum \returns \tcode{is_character_file(status(p))} or \tcode{is_character_file(status(p, ec))}, - respectively. The signature with argument \tcode{ec} returns \tcode{false} + respectively.\\The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum @@ -13942,9 +14526,9 @@ return \tcode{false} if an error occurred. \item Otherwise, if \tcode{is_directory(s)}: \begin{itemize} - \item Create \tcode{directory_iterator itr}, - as if by \tcode{directory_iterator(p)} or - \tcode{directory_iterator(p, ec)}, respectively. + \item Create a variable \tcode{itr}, + as if by \tcode{directory_iterator itr(p)} or + \tcode{directory_iterator itr(p, ec)}, respectively. \item For the signature with argument \tcode{ec}, return \tcode{false} if an error occurred. \item Otherwise, return \tcode{itr == directory_iterator()}. @@ -14167,38 +14751,28 @@ \indexlibrary{\idxcode{permissions}}% \begin{itemdecl} -void permissions(const path& p, perms prms); -void permissions(const path& p, perms prms, error_code& ec); +void permissions(const path& p, perms prms, perm_options opts=perm_options::replace); +void permissions(const path& p, perms prms, error_code& ec) noexcept; +void permissions(const path& p, perms prms, perm_options opts, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum - \requires \tcode{!((prms \& perms::add_perms) != perms::none \&\& (prms \& perms::remove_perms) != perms::none)}. + \requires Exactly one of the \tcode{perm_options} constants + \tcode{replace}, \tcode{add}, or \tcode{remove} is present in \tcode{opts}. \pnum -\effects Applies the effective permissions bits from \tcode{prms} - to the file \tcode{p} resolves to, or - if that file is a symbolic link and \tcode{symlink_nofollow} is not set in \tcode{prms}, - the file that it points to, - as if by POSIX \tcode{fchmodat()}. The effective permission bits are determined as - specified in Table~\ref{tab:fs.op.permissions}, - where \tcode{s} is the result of - \tcode{(prms \& perms::symlink_nofollow)} \tcode{!=} \tcode{perms::none} - \tcode{?} \tcode{symlink_status(p)} \tcode{:} \tcode{status(p)}. + \remarks The second signature behaves as if it had an additional parameter + \tcode{perm_options} \tcode{opts} with an argument of \tcode{perm_options::replace}. -\begin{floattable} -{Effects of permission bits}{tab:fs.op.permissions}{x{.30\hsize}x{.55\hsize}} -\topline -\lhdr{Bits present in \tcode{prms}} & - \rhdr{Effective bits applied} \\ \capsep -Neither \tcode{add_perms} nor \tcode{remove_perms} & - \tcode{prms \& perms::mask} \\ \rowsep -\tcode{add_perms} & - \tcode{s.permissions() | (prms \& perms::mask)} \\ \rowsep -\tcode{remove_perms} & - \tcode{s.permissions() \& \~(prms \& perms::mask)} \\ -\end{floattable} +\pnum + \effects Applies the action specified by \tcode{opts} + to the file \tcode{p} resolves to, + or to file \tcode{p} itself if \tcode{p} is a symbolic link + and \tcode{perm_options::nofollow} is set in \tcode{opts}. + The action is applied as if by POSIX \tcode{fchmodat()}. +\pnum \begin{note} Conceptually permissions are viewed as bits, but the actual implementation may use some other mechanism. \end{note} @@ -14520,7 +15094,7 @@ \tcode{} operations would fail on a directory. \end{note} \item Otherwise, if the attributes indicate a directory, as if by POSIX \tcode{S_ISDIR}, returns \tcode{file_status(file_type::directory, prms)}. - \begin{note} \tcode{file_type::directory} implies + \begin{note} \tcode{file_type::directory} implies that calling \tcode{directory_iterator(p)} would succeed. \end{note} \item Otherwise, if the attributes indicate a block special file, as if by POSIX \tcode{S_ISBLK}, returns \tcode{file_status(file_type::block, prms)}. @@ -14530,6 +15104,11 @@ POSIX \tcode{S_ISFIFO}, returns \tcode{file_status(file_type::fifo, prms)}. \item Otherwise, if the attributes indicate a socket, as if by POSIX \tcode{S_ISSOCK}, returns \tcode{file_status(file_type::socket, prms)}. +\item Otherwise, if the attributes indicate an implementation-defined + file type~(\ref{fs.enum.file_type}), + returns \tcode{file_status(file_type::\placeholdernc{A}, prms)}, + where \tcode{\placeholdernc{A}} is the constant for the + \impldef{file type of the file argument of \tcode{filesystem::status}} file type. \item Otherwise, returns \tcode{file_status(file_type::unknown, prms)}. \end{itemize} \end{itemize} @@ -14588,47 +15167,6 @@ \end{itemdescr} -\rSec3[fs.op.system_complete]{System complete} - -\indexlibrary{\idxcode{system_complete}}% -\begin{itemdecl} -path system_complete(const path& p); -path system_complete(const path& p, error_code& ec); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Composes an absolute path from \tcode{p}, using the - same rules used by the operating system to resolve a path passed as the - filename argument to standard library open functions. - -\pnum -\returns The composed path. The signature with argument \tcode{ec} - returns \tcode{path()} if an error occurs. - -\pnum -\postconditions For the returned path, \tcode{rp}, \tcode{rp.is_absolute()} is \tcode{true}. - -\pnum -\throws As specified in~\ref{fs.err.report}. - -\pnum -\begin{example} For POSIX-based operating systems, \tcode{system_complete(p)} - has the same semantics as \tcode{absolute(p, current_path())}. - -For Windows-based operating systems, \tcode{system_complete(p)} has the - same semantics as \tcode{absolute(p, current_path())} if - \tcode{p.is_absolute() || !p.has_root_name()} or - \tcode{p} and \tcode{current_path()} have the same \tcode{root_name()}. - Otherwise \tcode{system_complete(p)} acts as if \tcode{absolute(p, cwd)} is - the current directory for the \tcode{p.root_name()} drive. - For programs run by the command processor, however, the current directory - for the \tcode{p.root_name()} drive may have been set by a prior program, - and this may have unintended consequences. -\end{example} - -\end{itemdescr} - \rSec3[fs.op.temp_dir_path]{Temporary directory path} \indexlibrary{\idxcode{temp_directory_path}}% @@ -14693,7 +15231,7 @@ \pnum \remarks Implementations are encouraged to avoid unnecessary normalization such as - when \tcode{canonical()} has already been called on the entirety of \tcode{p}. + when \tcode{canonical} has already been called on the entirety of \tcode{p}. \pnum \throws As specified in~\ref{fs.err.report}. @@ -14952,7 +15490,7 @@ #define SCNiN @\seebelow@ #define SCNoN @\seebelow@ #define SCNuN @\seebelow@ -#define SCNxN @\seebelow@ +#define SCNxN @\seebelow@ #define PRIdLEASTN @\seebelow@ #define PRIiLEASTN @\seebelow@ #define PRIoLEASTN @\seebelow@ @@ -14963,7 +15501,7 @@ #define SCNiLEASTN @\seebelow@ #define SCNoLEASTN @\seebelow@ #define SCNuLEASTN @\seebelow@ -#define SCNxLEASTN @\seebelow@ +#define SCNxLEASTN @\seebelow@ #define PRIdFASTN @\seebelow@ #define PRIiFASTN @\seebelow@ #define PRIoFASTN @\seebelow@ @@ -14974,7 +15512,7 @@ #define SCNiFASTN @\seebelow@ #define SCNoFASTN @\seebelow@ #define SCNuFASTN @\seebelow@ -#define SCNxFASTN @\seebelow@ +#define SCNxFASTN @\seebelow@ #define PRIdMAX @\seebelow@ #define PRIiMAX @\seebelow@ #define PRIoMAX @\seebelow@ @@ -14985,7 +15523,7 @@ #define SCNiMAX @\seebelow@ #define SCNoMAX @\seebelow@ #define SCNuMAX @\seebelow@ -#define SCNxMAX @\seebelow@ +#define SCNxMAX @\seebelow@ #define PRIdPTR @\seebelow@ #define PRIiPTR @\seebelow@ #define PRIoPTR @\seebelow@ @@ -15012,7 +15550,7 @@ The header \tcode{} includes the header \tcode{} instead of \tcode{}, and \item -if and only if the type \tcode{intmax_t} designates an extended integer +if and only if the type \tcode{intmax_t} designates an extended integer type~(\ref{basic.fundamental}), the following function signatures are added: \begin{codeblock} intmax_t abs(intmax_t); diff --git a/source/iterators.tex b/source/iterators.tex index 0f2a6fcb2c..545bb01b55 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -753,7 +753,7 @@ const reverse_iterator& x); template - constexpr reverse_iterator make_reverse_iterator(Iterator i); + constexpr reverse_iterator make_reverse_iterator(Iterator i); template class back_insert_iterator; template @@ -1245,7 +1245,7 @@ const reverse_iterator& x); template - constexpr reverse_iterator make_reverse_iterator(Iterator i); + constexpr reverse_iterator make_reverse_iterator(Iterator i); } \end{codeblock} @@ -2426,7 +2426,7 @@ \begin{itemdescr} \pnum -\returns \tcode{std::move(}current[n]). +\returns \tcode{std::move(current[n])}. \end{itemdescr} \rSec4[move.iter.op.comp]{\tcode{move_iterator} comparisons} @@ -2597,6 +2597,8 @@ The behavior of a program that applies \tcode{operator++()} to an end-of-stream iterator is undefined. It is impossible to store things into istream iterators. +The type \tcode{T} shall meet the \tcode{DefaultConstructible}, +\tcode{CopyConstructible}, and \tcode{CopyAssignable} requirements. \pnum Two end-of-stream iterators are always equal. @@ -2619,10 +2621,10 @@ using traits_type = traits; using istream_type = basic_istream; - @\seebelow@ istream_iterator(); + constexpr istream_iterator(); istream_iterator(istream_type& s); istream_iterator(const istream_iterator& x) = default; - ~istream_iterator() = default; + ~istream_iterator() = default; const T& operator*() const; const T* operator->() const; @@ -2647,7 +2649,7 @@ \indexlibrary{\idxcode{istream_iterator}!constructor}% \begin{itemdecl} -@\seebelow@ istream_iterator(); +constexpr istream_iterator(); \end{itemdecl} \begin{itemdescr} @@ -2839,7 +2841,7 @@ ostream_iterator(ostream_type& s); ostream_iterator(ostream_type& s, const charT* delimiter); ostream_iterator(const ostream_iterator& x); - ~ostream_iterator(); + ~ostream_iterator(); ostream_iterator& operator=(const T& value); ostream_iterator& operator*(); @@ -2957,7 +2959,6 @@ from the streambuf for which it was constructed. \tcode{operator*} provides access to the current input character, if any. -\begin{note} \tcode{operator->} may return a proxy. \end{note} Each time \tcode{operator++} is evaluated, the iterator advances to the next input character. @@ -3011,7 +3012,6 @@ istreambuf_iterator(streambuf_type* s) noexcept; istreambuf_iterator(const proxy& p) noexcept; charT operator*() const; - pointer operator->() const; istreambuf_iterator& operator++(); proxy operator++(int); bool equal(const istreambuf_iterator& b) const; @@ -3028,7 +3028,7 @@ } \end{codeblock} -\rSec3[istreambuf.iterator::proxy]{Class template \tcode{istreambuf_iterator::proxy}} +\rSec3[istreambuf.iterator.proxy]{Class template \tcode{istreambuf_iterator::proxy}} \indexlibrary{\idxcode{proxy}!\idxcode{istreambuf_iterator}}% \begin{codeblock} @@ -3052,7 +3052,7 @@ An implementation is permitted to provide equivalent functionality without providing a class with this name. Class -\tcode{istreambuf_iterator\colcol{}proxy} +\tcode{istreambuf_iterator::proxy} provides a temporary placeholder as the return value of the post-increment operator (\tcode{operator++}). @@ -3114,7 +3114,7 @@ Initializes \tcode{sbuf_} with \tcode{p.sbuf_}. \end{itemdescr} -\rSec3[istreambuf.iterator::op*]{\tcode{istreambuf_iterator::operator*}} +\rSec3[istreambuf.iterator.ops]{\tcode{istreambuf_iterator} operations} \indexlibrarymember{operator*}{istreambuf_iterator}% \begin{itemdecl} @@ -3130,8 +3130,6 @@ \tcode{sbuf_->sgetc()}. \end{itemdescr} -\rSec3[istreambuf.iterator::op++]{\tcode{istreambuf_iterator::operator++}} - \indexlibrarymember{operator++}{istreambuf_iterator}% \begin{itemdecl} istreambuf_iterator& operator++(); @@ -3158,8 +3156,6 @@ \tcode{proxy(sbuf_->sbumpc(), sbuf_)}. \end{itemdescr} -\rSec3[istreambuf.iterator::equal]{\tcode{istreambuf_iterator::equal}} - \indexlibrarymember{equal}{istreambuf_iterator}% \begin{itemdecl} bool equal(const istreambuf_iterator& b) const; @@ -3175,8 +3171,6 @@ object they use. \end{itemdescr} -\rSec3[istreambuf.iterator::op==]{\tcode{operator==}} - \indexlibrarymember{operator==}{istreambuf_iterator}% \begin{itemdecl} template @@ -3190,8 +3184,6 @@ \tcode{a.equal(b)}. \end{itemdescr} -\rSec3[istreambuf.iterator::op!=]{\tcode{operator!=}} - \indexlibrarymember{operator"!=}{istreambuf_iterator}% \begin{itemdecl} template diff --git a/source/lex.tex b/source/lex.tex index ae457307bd..faeeb96f47 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1128,7 +1128,7 @@ character set, is conditionally-supported, has type \tcode{int}, \indextext{literal!multicharacter!implementation-defined value of}% and has an \impldef{value of multicharacter literal} value. - + \pnum \indextext{literal!character!UTF-8}% A character literal that @@ -1200,8 +1200,8 @@ is supported for compatibility with ISO \CppXIV and ISO C.} and the backslash \indextext{backslash character}% -\indextext{\idxcode{\textbackslash}|see{backslash}}% -\indextext{escape character|see{backslash}}% +\indextext{\idxcode{\textbackslash}|see{backslash character}}% +\indextext{escape character|see{backslash character}}% \tcode{\textbackslash}, can be represented according to Table~\ref{tab:escape.sequences}. \indextext{escape sequence!undefined}% @@ -1248,7 +1248,7 @@ sequence. A sequence of octal or hexadecimal digits is terminated by the first character that is not an octal digit or a hexadecimal digit, respectively. -\indextext{literal!implementation-defined value of \idxcode{char}}% +\indextext{literal!implementation-defined value of char@implementation-defined value of \tcode{char}}% The value of a character literal is \impldef{value of character literal outside range of corresponding type} if it falls outside of the \impldef{range defined for character literals} range defined for \tcode{char} (for character literals with no prefix) or diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 29c4ba456e..c9bfbbd03b 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -57,7 +57,7 @@ such as tuples, function wrappers, and time facilities. \pnum -The strings library (Clause~\ref{strings}) provides support for manipulating text represented +The strings library (Clause~\ref{strings}) provides support for manipulating text represented as sequences of type \tcode{char}, sequences of type @@ -128,7 +128,11 @@ \rSec1[definitions]{Definitions} \pnum -\begin{note} \ref{intro.defs} defines additional terms used elsewhere in this International Standard. \end{note} +\begin{note} +Clause \ref{intro.defs} defines additional terms used elsewhere in this International Standard. +\end{note} + +\def\definition{\definitionx{\subsection}}% \definition{arbitrary-positional stream}{defns.arbitrary.stream} \indexdefn{stream!arbitrary-positional}% @@ -212,6 +216,11 @@ \term{handler function} semantics +\definition{direct-non-list-initialization}{defns.direct-non-list-init} +\indexdefn{direct-non-list-initialization}% +a direct-initialization~(\ref{dcl.init}) +that is not list-initialization~(\ref{dcl.init.list}) + \definition{handler function}{defns.handler} \indexdefn{function!handler}% a @@ -265,17 +274,9 @@ value \tcode{charT()} -\definition{object state}{defns.obj.state} -\indexdefn{state!object}% -the current value of all non-static class members of an object~(\ref{class.mem})\\ -\begin{note} -The state of an object can be obtained by using one or more -\term{observer functions}. -\end{note} - \definition{observer function}{defns.observer} \indexdefn{function!observer}% -a class member function~(\ref{class.mfct}) that accesses the state of an object of the class +a class member function~(\ref{class.mfct}) that accesses the state of an object of the class but does not alter that state\\ \begin{note} Observer functions are specified as @@ -344,7 +345,7 @@ \definition{valid but unspecified state}{defns.valid} \indexdefn{valid but unspecified state}% -an object state that is not specified except that the object's invariants are +a value of an object that is not specified except that the object's invariants are met and operations on the object behave as specified for its type\\ \begin{example} If an object \tcode{x} of type \tcode{std::vector} is in a valid but unspecified state, \tcode{x.empty()} can be called unconditionally, @@ -604,20 +605,21 @@ values~(\ref{basic.fundamental}).} \pnum -The enumerated type \term{enumerated} can be written: +The enumerated type \tcode{\placeholder{enumerated}} can be written: \begin{codeblock} -enum @\term{enumerated}@ { @\term{V0}@, @\term{V1}@, @\term{V2}@, @\term{V3}@, ..... }; +enum @\placeholder{enumerated}@ { @$\tcode{\placeholder{V}}_{0}$@, @$\tcode{\placeholder{V}}_{1}$@, @$\tcode{\placeholder{V}}_{2}$@, @$\tcode{\placeholder{V}}_{3}$@, ..... }; -static const @\term{enumerated C0}@ (@\term{V0}@); -static const @\term{enumerated C1}@ (@\term{V1}@); -static const @\term{enumerated C2}@ (@\term{V2}@); -static const @\term{enumerated C3}@ (@\term{V3}@); +inline const @$\tcode{\placeholder{enumerated C}}_{0}$@(@$\tcode{\placeholder{V}}_{0}$@); +inline const @$\tcode{\placeholder{enumerated C}}_{1}$@(@$\tcode{\placeholder{V}}_{1}$@); +inline const @$\tcode{\placeholder{enumerated C}}_{2}$@(@$\tcode{\placeholder{V}}_{2}$@); +inline const @$\tcode{\placeholder{enumerated C}}_{3}$@(@$\tcode{\placeholder{V}}_{3}$@); ..... \end{codeblock} \pnum -Here, the names \term{C0}, \term{C1}, etc. represent +Here, the names $\tcode{\placeholder{C}}_0$, +$\tcode{\placeholder{C}}_1$, etc.\ represent \term{enumerated elements} for this particular enumerated type. \indextext{type!enumerated}% @@ -641,16 +643,15 @@ \begin{codeblock} // For exposition only. -// \tcode{int_type} is an integral type capable of -// representing all values of the bitmask type. -enum @\term{bitmask}@ : int_type { - @\term{V0}@ = 1 << 0, @\term{V1}@ = 1 << 1, @\term{V2}@ = 1 << 2, @\term{V3}@ = 1 << 3, ..... +// \tcode{int_type} is an integral type capable of representing all values of the bitmask type. +enum @\placeholder{bitmask}@ : int_type { + @$\tcode{\placeholder{V}}_{0}$@ = 1 << 0, @$\tcode{\placeholder{V}}_{1}$@ = 1 << 1, @$\tcode{\placeholder{V}}_{2}$@ = 1 << 2, @$\tcode{\placeholder{V}}_{3}$@ = 1 << 3, ..... }; -constexpr @\term{bitmask C0}@(@\term{V0}{}@); -constexpr @\term{bitmask C1}@(@\term{V1}{}@); -constexpr @\term{bitmask C2}@(@\term{V2}{}@); -constexpr @\term{bitmask C3}@(@\term{V3}{}@); +inline constexpr @$\tcode{\placeholder{bitmask C}}_{0}$@(@$\tcode{\placeholder{V}}_{0}{}$@); +inline constexpr @$\tcode{\placeholder{bitmask C}}_{1}$@(@$\tcode{\placeholder{V}}_{1}{}$@); +inline constexpr @$\tcode{\placeholder{bitmask C}}_{2}$@(@$\tcode{\placeholder{V}}_{2}{}$@); +inline constexpr @$\tcode{\placeholder{bitmask C}}_{3}$@(@$\tcode{\placeholder{V}}_{3}{}$@); ..... constexpr @\term{bitmask}{}@ operator&(@\term{bitmask}{}@ X, @\term{bitmask}{}@ Y) { @@ -680,21 +681,21 @@ \end{codeblock} \pnum -Here, the names \term{C0}, \term{C1}, etc. represent +Here, the names $\tcode{\placeholder{C}}_0$, +$\tcode{\placeholder{C}}_1$, etc.\ represent \term{bitmask elements} for this particular bitmask type. \indextext{type!bitmask}% -All such elements have distinct, nonzero values such that, for any pair \term{Ci} -and \term{Cj} where \term{i} != \term{j}, \term{Ci} \& \term{Ci} is nonzero and -\term{Ci} \& \term{Cj} is zero. +All such elements have distinct, nonzero values such that, for any pair $\tcode{\placeholder{C}}_i$ +and $\tcode{\placeholder{C}}_j$ where $i \neq j$, \tcode{$\placeholder{C}_i$ \& $\placeholder{C}_i$} is nonzero and +\tcode{$\placeholder{C}_i$ \& $\placeholder{C}_j$} is zero. \indextext{bitmask!empty}% -Additionally, the value 0 is used to represent an \term{empty bitmask}, in which no +Additionally, the value \tcode{0} is used to represent an \term{empty bitmask}, in which no bitmask elements are set. \pnum The following terms apply to objects and values of bitmask types: - \begin{itemize} \item To @@ -758,10 +759,10 @@ \item A \term{character sequence} -is an array object~(\ref{dcl.array}) \textit{A} that +is an array object~(\ref{dcl.array}) \tcode{\placeholdernc{A}} that can be declared as -\tcode{\textit{T A}[\textit{N}]}, -where \textit{T} is any of the types +\tcode{\placeholdernc{T\;A}[\placeholder{N}]}, +where \tcode{\placeholder{T}} is any of the types \tcode{char}, \tcode{unsigned char}, or @@ -773,7 +774,7 @@ array have defined contents up to and including an element determined by some predicate. A character sequence can be designated by a pointer value -\textit{S} that points to its first element. +\tcode{\placeholder{S}} that points to its first element. \end{itemize} \rSec5[byte.strings]{Byte strings} @@ -829,13 +830,10 @@ \rSec5[multibyte.strings]{Multibyte strings} \pnum -A \indextext{NTBS}% \indextext{NTMBS}% -\term{null-terminated multibyte string,} -or \ntmbs, -\indextext{string!null-terminated multibyte}% -is an \ntbs that constitutes a +A \defnx{null-terminated multibyte string}{string!null-terminated multibyte}, +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. @@ -1110,7 +1108,7 @@ Except as noted in Clauses~\ref{library} through~\ref{\lastlibchapter} and Annex~\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~(\ref{intro.refs}). +specified in the C standard library (Clause~\ref{intro.refs}). In the \Cpp standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope~(\ref{basic.scope.namespace}) of the namespace \tcode{std}. @@ -1283,18 +1281,19 @@ include at least the headers shown in Table~\ref{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 -\ref{cstdint} & Integer types & \tcode{} \\ \rowsep -\ref{support.start.term}& Start and termination & \tcode{} \\ \rowsep -\ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep -\ref{support.rtti} & Type identification & \tcode{} \\ \rowsep -\ref{support.exception} & Exception handling & \tcode{} \\ \rowsep -\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep -\ref{support.runtime} & Other runtime support & \tcode{} \tcode{} \tcode{} \\ \rowsep -\ref{meta} & Type traits & \tcode{} \\ \rowsep -\ref{atomics} & Atomics & \tcode{} \\ + & & \tcode{} \\ \rowsep +\ref{support.types} & Types & \tcode{} \\ \rowsep +\ref{support.limits} & Implementation properties & \tcode{} \tcode{} \tcode{} \\ \rowsep +\ref{cstdint} & Integer types & \tcode{} \\ \rowsep +\ref{support.start.term} & Start and termination & \tcode{} \\ \rowsep +\ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep +\ref{support.rtti} & Type identification & \tcode{} \\ \rowsep +\ref{support.exception} & Exception handling & \tcode{} \\ \rowsep +\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep +\ref{support.runtime} & Other runtime support & \tcode{} \\ \rowsep +\ref{meta} & Type traits & \tcode{} \\ \rowsep +\ref{atomics} & Atomics & \tcode{} \\ \rowsep +\ref{depr.cstdalign.syn}, \ref{depr.cstdbool.syn} & Deprecated headers & \tcode{} \tcode{} \\ \end{libsumtab} \pnum @@ -1393,7 +1392,8 @@ the program prior to program startup. \indextext{startup!program}% -\xref +\pnum +See also replacement functions~(\ref{replacement.functions}), runtime changes~(\ref{handler.functions}). @@ -1438,7 +1438,7 @@ \begin{concepttable}{\tcode{EqualityComparable} requirements}{equalitycomparable} {x{1in}x{1in}p{3in}} \topline -Expression & Return type & \multicolumn{1}{c|}{Requirement} \\ \capsep +\hdstyle{Expression} & \hdstyle{Return type} & \rhdr{Requirement} \\ \capsep \tcode{a == b} & convertible to \tcode{bool} & \tcode{==} is an equivalence relation, @@ -1457,7 +1457,7 @@ \begin{concepttable}{\tcode{LessThanComparable} requirements}{lessthancomparable} {x{1in}x{1in}p{3in}} \topline -Expression & Return type & Requirement \\ \capsep +\hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Requirement} \\ \capsep \tcode{a < b} & convertible to \tcode{bool} & \tcode{<} is a strict weak ordering relation~(\ref{alg.sorting}) \\ @@ -1468,7 +1468,7 @@ \begin{concepttable}{\tcode{DefaultConstructible} requirements}{defaultconstructible} {x{2.15in}p{3in}} \topline -Expression & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep \tcode{T t;} & object \tcode{t} is default-initialized \\ \rowsep \tcode{T u\{\};} & object \tcode{u} is value-initialized or aggregate-initialized \\ \rowsep \tcode{T()}\br\tcode{T\{\}} & an object of type \tcode{T} is value-initialized @@ -1479,7 +1479,7 @@ \begin{concepttable}{\tcode{MoveConstructible} requirements}{moveconstructible} {p{1in}p{4.15in}} \topline -Expression & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep \tcode{T u = rv;} & \tcode{u} is equivalent to the value of \tcode{rv} before the construction\\ \rowsep \tcode{T(rv)} & \tcode{T(rv)} is equivalent to the value of \tcode{rv} before the construction \\ \rowsep @@ -1494,7 +1494,7 @@ \begin{concepttable}{\tcode{CopyConstructible} requirements (in addition to \tcode{MoveConstructible})}{copyconstructible} {p{1in}p{4.15in}} \topline -Expression & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep \tcode{T u = v;} & the value of \tcode{v} is unchanged and is equivalent to \tcode{ u}\\ \rowsep \tcode{T(v)} & the value of \tcode{v} is unchanged and is equivalent to \tcode{T(v)} \\ @@ -1504,7 +1504,7 @@ \begin{concepttable}{\tcode{MoveAssignable} requirements}{moveassignable} {p{1in}p{1in}p{1in}p{1.9in}} \topline -Expression & Return type & Return value & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Return value} & \hdstyle{Post-condition} \\ \capsep \tcode{t = rv} & \tcode{T\&} & \tcode{t} & If \tcode{t} and \tcode{rv} do not refer to the same object, \tcode{t} is equivalent to the value of \tcode{rv} before the assignment\\ \rowsep @@ -1520,7 +1520,7 @@ \begin{concepttable}{\tcode{CopyAssignable} requirements (in addition to \tcode{MoveAssignable})}{copyassignable} {p{1in}p{1in}p{1in}p{1.9in}} \topline -Expression & Return type & Return value & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Return value} & \hdstyle{Post-condition} \\ \capsep \tcode{t = v} & \tcode{T\&} & \tcode{t} & \tcode{t} is equivalent to \tcode{v}, the value of \tcode{v} is unchanged\\ \end{concepttable} @@ -1528,7 +1528,7 @@ \begin{concepttable}{\tcode{Destructible} requirements}{destructible} {p{1in}p{4.15in}} \topline -Expression & Post-condition \\ \capsep +\hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep \tcode{u.\~T()} & All resources owned by \tcode{u} are reclaimed, no exception is propagated. \\ \end{concepttable} @@ -1881,13 +1881,17 @@ type of \tcode{T::m} & \requires \tcode{(*q).m} is well-defined. equivalent to \tcode{(*q).m} & \\ \rowsep -\tcode{static_-} \tcode{cast(w)} & +\tcode{static_cast<\brk{}X::pointer\brk{}>(w)} & \tcode{X::pointer} & - \tcode{static_cast(w)} \tcode{== p} & \\ \rowsep + \tcode{static_cast(w) == p} & \\ \rowsep -\tcode{static_cast(x)} & +\tcode{static_cast<\brk{}X::const_pointer\brk{}>(x)} & \tcode{X::const_pointer} & - \tcode{static_cast(x)} \tcode{== q} & \\ \rowsep + \tcode{static_cast<} \tcode{X::const_pointer\brk{}>(x) == q} & \\ \rowsep + +\tcode{pointer_traits<\brk{}X::pointer\brk{}>::pointer_to(r)} & + \tcode{X::pointer} & + & \\ \rowsep \tcode{a.allocate(n)} & \tcode{X::pointer} & Memory is allocated for \tcode{n} objects of type \tcode{T} but objects @@ -1913,7 +1917,7 @@ \tcode{a.max_size()} & \tcode{X::size_type} & the largest value that can meaningfully be passed to \tcode{X::allocate()} & - \tcode{numeric_limits::max()/\brk{}sizeof(value_type)} \\ \rowsep + \tcode{numeric_limits::max() / sizeof\brk{}(value_type)} \\ \rowsep \tcode{a1 == a2} & \tcode{bool} & @@ -2045,8 +2049,9 @@ No constructor, comparison function, copy operation, move operation, or swap operation on these pointer types shall exit via an exception. \tcode{X::pointer} and \tcode{X::const_pointer} shall also -satisfy the requirements for a random access -iterator~(\ref{iterator.requirements}). +satisfy the requirements for +a random access iterator~(\ref{random.access.iterators}) and of +a contiguous iterator~(\ref{iterator.requirements.general}). \pnum Let \tcode{x1} and \tcode{x2} denote objects of (possibly different) types @@ -2129,7 +2134,7 @@ \begin{itemize} \item \tcode{X} is a complete type, and -\item all the member types of \tcode{allocator_traits}~\ref{allocator.traits} +\item all the member types of \tcode{allocator_traits}~(\ref{allocator.traits}) other than \tcode{value_type} are complete types. \end{itemize} @@ -2176,7 +2181,9 @@ standard library class or class template, or \item an explicit or partial specialization of any member class template -of a standard library class or class template. +of a standard library class or class template, or + +\item a deduction guide for any standard library class template. \end{itemize} A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type @@ -2231,31 +2238,34 @@ \pnum In namespace \tcode{std}, the following names are reserved for previous standardization: -\indexlibrary{\idxcode{auto_ptr}!zombie} \tcode{auto_ptr}, -\indexlibrary{\idxcode{binary_function}!zombie} \tcode{binary_function}, -\indexlibrary{\idxcode{bind1st}!zombie} \tcode{bind1st}, -\indexlibrary{\idxcode{bind2nd}!zombie} \tcode{bind2nd}, -\indexlibrary{\idxcode{binder1st}!zombie} \tcode{binder1st}, -\indexlibrary{\idxcode{binder2nd}!zombie} \tcode{binder2nd}, -\indexlibrary{\idxcode{const_mem_fun1_ref_t}!zombie} \tcode{const_mem_fun1_ref_t}, -\indexlibrary{\idxcode{const_mem_fun1_t}!zombie} \tcode{const_mem_fun1_t}, -\indexlibrary{\idxcode{const_mem_fun_ref_t}!zombie} \tcode{const_mem_fun_ref_t}, -\indexlibrary{\idxcode{const_mem_fun_t}!zombie} \tcode{const_mem_fun_t}, -\indexlibrary{\idxcode{get_unexpected}!zombie} \tcode{get_unexpected}, -\indexlibrary{\idxcode{mem_fun1_ref_t}!zombie} \tcode{mem_fun1_ref_t}, -\indexlibrary{\idxcode{mem_fun1_t}!zombie} \tcode{mem_fun1_t}, -\indexlibrary{\idxcode{mem_fun_ref_t}!zombie} \tcode{mem_fun_ref_t}, -\indexlibrary{\idxcode{mem_fun_ref}!zombie} \tcode{mem_fun_ref}, -\indexlibrary{\idxcode{mem_fun_t}!zombie} \tcode{mem_fun_t}, -\indexlibrary{\idxcode{mem_fun}!zombie} \tcode{mem_fun}, -\indexlibrary{\idxcode{pointer_to_binary_function}!zombie} \tcode{pointer_to_binary_function}, -\indexlibrary{\idxcode{pointer_to_unary_function}!zombie} \tcode{pointer_to_unary_function}, -\indexlibrary{\idxcode{ptr_fun}!zombie} \tcode{ptr_fun}, -\indexlibrary{\idxcode{random_shuffle}!zombie} \tcode{random_shuffle}, -\indexlibrary{\idxcode{set_unexpected}!zombie} \tcode{set_unexpected}, -\indexlibrary{\idxcode{unary_function}!zombie} \tcode{unary_function}, -\indexlibrary{\idxcode{unexpected}!zombie} \tcode{unexpected}, -and \indexlibrary{\idxcode{unexpected_handler}!zombie} \tcode{unexpected_handler}. +\begin{itemize} +\item \indexlibrary{\idxcode{auto_ptr}!zombie} \tcode{auto_ptr}, +\item \indexlibrary{\idxcode{binary_function}!zombie} \tcode{binary_function}, +\item \indexlibrary{\idxcode{bind1st}!zombie} \tcode{bind1st}, +\item \indexlibrary{\idxcode{bind2nd}!zombie} \tcode{bind2nd}, +\item \indexlibrary{\idxcode{binder1st}!zombie} \tcode{binder1st}, +\item \indexlibrary{\idxcode{binder2nd}!zombie} \tcode{binder2nd}, +\item \indexlibrary{\idxcode{const_mem_fun1_ref_t}!zombie} \tcode{const_mem_fun1_ref_t}, +\item \indexlibrary{\idxcode{const_mem_fun1_t}!zombie} \tcode{const_mem_fun1_t}, +\item \indexlibrary{\idxcode{const_mem_fun_ref_t}!zombie} \tcode{const_mem_fun_ref_t}, +\item \indexlibrary{\idxcode{const_mem_fun_t}!zombie} \tcode{const_mem_fun_t}, +\item \indexlibrary{\idxcode{get_unexpected}!zombie} \tcode{get_unexpected}, +\item \indexlibrary{\idxcode{mem_fun1_ref_t}!zombie} \tcode{mem_fun1_ref_t}, +\item \indexlibrary{\idxcode{mem_fun1_t}!zombie} \tcode{mem_fun1_t}, +\item \indexlibrary{\idxcode{mem_fun_ref_t}!zombie} \tcode{mem_fun_ref_t}, +\item \indexlibrary{\idxcode{mem_fun_ref}!zombie} \tcode{mem_fun_ref}, +\item \indexlibrary{\idxcode{mem_fun_t}!zombie} \tcode{mem_fun_t}, +\item \indexlibrary{\idxcode{mem_fun}!zombie} \tcode{mem_fun}, +\item \indexlibrary{\idxcode{pointer_to_binary_function}!zombie} \tcode{pointer_to_binary_function}, +\item \indexlibrary{\idxcode{pointer_to_unary_function}!zombie} \tcode{pointer_to_unary_function}, +\item \indexlibrary{\idxcode{ptr_fun}!zombie} \tcode{ptr_fun}, +\item \indexlibrary{\idxcode{random_shuffle}!zombie} \tcode{random_shuffle}, +\item \indexlibrary{\idxcode{set_unexpected}!zombie} \tcode{set_unexpected}, +\item \indexlibrary{\idxcode{unary_function}!zombie} \tcode{unary_function}, +\item \indexlibrary{\idxcode{unexpected}!zombie} \tcode{unexpected}, +and +\item \indexlibrary{\idxcode{unexpected_handler}!zombie} \tcode{unexpected_handler}. +\end{itemize} \rSec4[macro.names]{Macro names} @@ -2344,7 +2354,7 @@ \indexlibrary{\idxhdr{cwchar}}% \indextext{\idxhdr{cwctype}}% \indexlibrary{\idxhdr{cwctype}}% -\tcode{}, +\tcode{}, \tcode{}, and \tcode{} @@ -2487,22 +2497,15 @@ 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} -\item -\indexlibrary{\idxcode{set_new_handler}}% -\tcode{set_new_handler} -\item -\indexlibrary{\idxcode{set_terminate}} -\tcode{set_terminate} - -\xref -subclauses~\ref{alloc.errors}, Storage allocation errors, and~\ref{support.exception}, -Exception handling. +\item \indexlibrary{\idxcode{set_new_handler}}\tcode{set_new_handler} +\item \indexlibrary{\idxcode{set_terminate}}\tcode{set_terminate} \end{itemize} +See also subclauses~\ref{alloc.errors}, Storage allocation errors, and~\ref{support.exception}, +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} @@ -2689,7 +2692,7 @@ It is unspecified whether any non-member functions in the \Cpp standard library are defined as -\tcode{inline}~(\ref{dcl.fct.spec}). +\tcode{inline}~(\ref{dcl.inline}). \pnum A call to a non-member function signature @@ -2705,12 +2708,14 @@ with additional default arguments. \pnum -Unless otherwise specified, non-member functions in the standard -library shall not use functions from another namespace which are found through +Unless otherwise specified, +calls made by functions in the standard library to non-operator, non-member functions +do not use functions from another namespace which are found through \term{argument-dependent name lookup}~(\ref{basic.lookup.argdep}). \begin{note} -The phrase ``unless otherwise specified'' is intended to allow -argument-dependent lookup +The phrase ``unless otherwise specified'' applies to cases such as +the swappable with requirements~(\ref{swappable.requirements}). +The exception for overloaded operators allows argument-dependent lookup in cases like that of \tcode{ostream_iterator::operator=}~(\ref{ostream.iterator.ops}): @@ -2727,7 +2732,7 @@ \pnum It is unspecified whether any member functions in the \Cpp standard library are defined as -\tcode{inline}~(\ref{dcl.fct.spec}). +\tcode{inline}~(\ref{dcl.inline}). \pnum For a non-virtual member function described in the \Cpp standard library, @@ -2749,7 +2754,7 @@ \tcode{constexpr}~(\ref{dcl.constexpr}). An implementation shall not declare any standard library function signature as \tcode{constexpr} except for those where it is explicitly required. -Within any header that provides any non-defining declarations of \tcode{constexpr} +Within any header that provides any non-defining declarations of constexpr functions or constructors an implementation shall provide corresponding definitions. \rSec3[algorithm.stable]{Requirements for stable algorithms} @@ -2866,10 +2871,8 @@ shall be virtual; \indextext{class!base}% \item -Every base class described as -non-\tcode{virtual} -shall not be virtual; -\indextext{class!base}% +Every base class not specified as +\tcode{virtual} shall not be virtual; \item Unless explicitly stated otherwise, types with distinct names shall be distinct types.\footnote{There is an implicit exception to this rule for types that are diff --git a/source/limits.tex b/source/limits.tex index 1e12db5f85..d1b2c85773 100644 --- a/source/limits.tex +++ b/source/limits.tex @@ -43,7 +43,7 @@ \item% Identifiers with block scope declared in one block [1\,024]. \item% -Identifiers introduced in one decomposition declaration [256]. +Structured bindings introduced in one declaration [256]. \item% Macro identifiers simultaneously defined in one translation diff --git a/source/locales.tex b/source/locales.tex index 49b4e9b6ed..256774c070 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -19,7 +19,6 @@ \begin{libsumtab}{Localization library summary}{tab:localization.lib.summary} \ref{locales} & Locales & \tcode{} \\ \ref{locale.categories} & Standard \tcode{locale} Categories & \\ \rowsep -\ref{locale.stdcvt} & Standard code conversion facets & \tcode{} \\ \rowsep \ref{c.locales} & C library locales & \tcode{} \\ \end{libsumtab} @@ -49,13 +48,6 @@ 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 , - class Byte_alloc = allocator> - class wstring_convert; - template > - class wbuffer_convert; // \ref{category.ctype}, ctype class ctype_base; @@ -897,7 +889,7 @@ otherwise, the effect on the C locale, if any, is \impldef{effect on C locale of calling \tcode{locale::global}}. No library function other than -\tcode{locale\colcol{}global()} +\tcode{locale::global()} shall affect the value returned by \tcode{locale()}. \begin{note} See~\ref{c.locales} for data race considerations when @@ -1047,398 +1039,6 @@ \tcode{use_facet>(loc).tolower(c)}. \end{itemdescr} -\rSec4[conversions.string]{Class template \tcode{wstring_convert}} - -\pnum -Class template \tcode{wstring_convert} performs conversions between a wide -string and a byte string. It lets you specify a code conversion facet -(like class template \tcode{codecvt}) to perform the conversions, without -affecting any streams or locales. \begin{example} If you want to use the code -conversion facet \tcode{codecvt_utf8} to output to \tcode{cout} a UTF-8 -multibyte sequence corresponding to a wide string, but you don't want to -alter the locale for \tcode{cout}, you can write something like: - -\begin{codeblock} -wstring_convert> myconv; -std::string mbstring = myconv.to_bytes(L"Hello\n"); -std::cout << mbstring; -\end{codeblock} -\end{example} - -\indexlibrary{\idxcode{wstring_convert}}% -\begin{codeblock} -namespace std { -template , - class Byte_alloc = allocator> - class wstring_convert { - public: - using byte_string = basic_string, Byte_alloc>; - using wide_string = basic_string, Wide_alloc>; - using state_type = typename Codecvt::state_type; - using int_type = typename wide_string::traits_type::int_type; - - explicit wstring_convert(Codecvt* pcvt = new Codecvt); - wstring_convert(Codecvt* pcvt, state_type state); - explicit wstring_convert(const byte_string& byte_err, - const wide_string& wide_err = wide_string()); - ~wstring_convert(); - - wstring_convert(const wstring_convert&) = delete; - wstring_convert& operator=(const wstring_convert&) = delete; - - wide_string from_bytes(char byte); - wide_string from_bytes(const char* ptr); - wide_string from_bytes(const byte_string& str); - wide_string from_bytes(const char* first, const char* last); - - byte_string to_bytes(Elem wchar); - byte_string to_bytes(const Elem* wptr); - byte_string to_bytes(const wide_string& wstr); - byte_string to_bytes(const Elem* first, const Elem* last); - - size_t converted() const noexcept; - state_type state() const; - - private: - byte_string byte_err_string; // \expos - wide_string wide_err_string; // \expos - Codecvt* cvtptr; // \expos - state_type cvtstate; // \expos - size_t cvtcount; // \expos - }; -} -\end{codeblock} - -\pnum -The class template describes an object that controls conversions between wide -string objects of class \tcode{basic_string, -Wide_alloc>} and byte string objects of class \tcode{basic_string, Byte_alloc>}. The class template defines the types -\tcode{wide_string} and \tcode{byte_string} as synonyms for these two types. -Conversion between a sequence of \tcode{Elem} values (stored in a -\tcode{wide_string} object) and multibyte sequences (stored in a -\tcode{byte_string} object) is performed by an object of class -\tcode{Codecvt}, which meets the -requirements of the standard code-conversion facet \tcode{codecvt}. - -\pnum -An object of this class template stores: - -\begin{itemize} -\item \tcode{byte_err_string} --- a byte string to display on errors -\item \tcode{wide_err_string} --- a wide string to display on errors -\item \tcode{cvtptr} --- a pointer to the allocated conversion object -(which is freed when the \tcode{wstring_convert} object is destroyed) -\item \tcode{cvtstate} --- a conversion state object -\item \tcode{cvtcount} --- a conversion count -\end{itemize} - -\indexlibrarymember{byte_string}{wstring_convert}% -\begin{itemdecl} -using byte_string = basic_string, Byte_alloc>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type shall be a synonym for \tcode{basic_string, Byte_alloc>} -\end{itemdescr} - -\indexlibrarymember{converted}{wstring_convert}% -\begin{itemdecl} -size_t converted() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{cvtcount}. -\end{itemdescr} - -\indexlibrarymember{from_bytes}{wstring_convert}% -\begin{itemdecl} -wide_string from_bytes(char byte); -wide_string from_bytes(const char* ptr); -wide_string from_bytes(const byte_string& str); -wide_string from_bytes(const char* first, const char* last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The first member function shall convert the single-element sequence \tcode{byte} to a -wide string. The second member function shall convert the null-terminated -sequence beginning at \tcode{ptr} to a wide string. The third member function -shall convert the sequence stored in \tcode{str} to a wide string. The fourth member -function shall convert the sequence defined by the range \range{first}{last} to a -wide string. - -\pnum -In all cases: - -\begin{itemize} -\item If the \tcode{cvtstate} object was not constructed with an explicit value, it -shall be set to its default value (the initial conversion state) before the -conversion begins. Otherwise it shall be left unchanged. - -\item The number of input elements successfully converted shall be stored in \tcode{cvtcount}. -\end{itemize} - -\pnum -\returns -If no conversion error occurs, the member function shall return the converted wide string. -Otherwise, if the object was constructed with a wide-error string, the -member function shall return the wide-error string. -Otherwise, the member function throws an object of class \tcode{range_error}. -\end{itemdescr} - -\indexlibrarymember{int_type}{wstring_convert}% -\begin{itemdecl} -using int_type = typename wide_string::traits_type::int_type; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type shall be a synonym for \tcode{wide_string::traits_type::int_type}. -\end{itemdescr} - -\indexlibrarymember{state}{wstring_convert}% -\begin{itemdecl} -state_type state() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -returns \tcode{cvtstate}. -\end{itemdescr} - -\indexlibrarymember{state_type}{wstring_convert}% -\begin{itemdecl} -using state_type = typename Codecvt::state_type; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type shall be a synonym for \tcode{Codecvt::state_type}. -\end{itemdescr} - -\indexlibrarymember{to_bytes}{wstring_convert}% -\begin{itemdecl} -byte_string to_bytes(Elem wchar); -byte_string to_bytes(const Elem* wptr); -byte_string to_bytes(const wide_string& wstr); -byte_string to_bytes(const Elem* first, const Elem* last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The first member function shall convert the single-element sequence \tcode{wchar} to a byte string. -The second member function shall convert the null-terminated sequence beginning at \tcode{wptr} to -a byte string. The third member function shall convert the sequence stored in \tcode{wstr} to a -byte string. The fourth member function shall convert the sequence defined by the -range \range{first}{last} to a byte string. - -\pnum -In all cases: - -\begin{itemize} -\item If the \tcode{cvtstate} object was not constructed with an explicit value, it -shall be -set to its default value (the initial conversion state) before the -conversion begins. Otherwise it shall be left unchanged. -\item The number of input elements successfully converted shall be stored -in \tcode{cvtcount}. -\end{itemize} - -\pnum -\returns -If no conversion error occurs, the member function shall return the converted byte string. -Otherwise, if the object was constructed with a byte-error string, the -member function shall return the byte-error string. -Otherwise, the member function shall throw an object of class \tcode{range_error}. -\end{itemdescr} - -\indexlibrarymember{wide_string}{wstring_convert}% -\begin{itemdecl} -using wide_string = basic_string, Wide_alloc>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type shall be a synonym for \tcode{basic_string, Wide_alloc>}. -\end{itemdescr} - -\indexlibrary{\idxcode{wstring_convert}!constructor}% -\begin{itemdecl} -explicit wstring_convert(Codecvt* pcvt = new Codecvt); -wstring_convert(Codecvt* pcvt, state_type state); -explicit wstring_convert(const byte_string& byte_err, - const wide_string& wide_err = wide_string()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -For the first and second constructors, \tcode{pcvt != nullptr}. - -\pnum -\effects -The first constructor shall store \tcode{pcvt} in \tcode{cvtptr} and -default values in \tcode{cvtstate}, \tcode{byte_err_string}, and -\tcode{wide_err_string}. -The second constructor shall store \tcode{pcvt} in \tcode{cvtptr}, -\tcode{state} in \tcode{cvtstate}, and default values in -\tcode{byte_err_string} and \tcode{wide_err_string}; moreover the -stored state shall be retained between calls to \tcode{from_bytes} and -\tcode{to_bytes}. -The third constructor shall store \tcode{new Codecvt} in \tcode{cvtptr}, -\tcode{state_type()} in \tcode{cvtstate}, \tcode{byte_err} -in \tcode{byte_err_string}, and \tcode{wide_err} in -\tcode{wide_err_string}. -\end{itemdescr} - -\indexlibrary{\idxcode{wstring_convert}!destructor}% -\begin{itemdecl} -~wstring_convert(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects The destructor shall delete \tcode{cvtptr}. -\end{itemdescr} - -\rSec4[conversions.buffer]{Class template \tcode{wbuffer_convert}} - -\pnum -Class template \tcode{wbuffer_convert} looks like a wide stream buffer, but -performs all its I/O through an underlying byte stream buffer that you -specify when you construct it. Like class template \tcode{wstring_convert}, it -lets you specify a code conversion facet to perform the conversions, -without affecting any streams or locales. - -\indexlibrary{\idxcode{wbuffer_convert}}% -\begin{codeblock} -namespace std { -template > - class wbuffer_convert - : public basic_streambuf { - public: - using state_type = typename Codecvt::state_type; - - explicit wbuffer_convert(streambuf* bytebuf = 0, - Codecvt* pcvt = new Codecvt, - state_type state = state_type()); - - ~wbuffer_convert(); - - wbuffer_convert(const wbuffer_convert&) = delete; - wbuffer_convert& operator=(const wbuffer_convert&) = delete; - - streambuf* rdbuf() const; - streambuf* rdbuf(streambuf* bytebuf); - - state_type state() const; - - private: - streambuf* bufptr; // \expos - Codecvt* cvtptr; // \expos - state_type cvtstate; // \expos - }; -} -\end{codeblock} - -\pnum -The class template describes a stream buffer that controls the -transmission of elements of type \tcode{Elem}, whose character traits are -described by the class \tcode{Tr}, to and from a byte stream buffer of type -\tcode{streambuf}. Conversion between a sequence of \tcode{Elem} values and -multibyte sequences is performed by an object of class -\tcode{Codecvt}, which shall meet the requirements -of the standard code-conversion facet \tcode{codecvt}. - -\pnum -An object of this class template stores: - -\begin{itemize} -\item \tcode{bufptr} --- a pointer to its underlying byte stream buffer -\item \tcode{cvtptr} --- a pointer to the allocated conversion object -(which is freed when the \tcode{wbuffer_convert} object is destroyed) -\item \tcode{cvtstate} --- a conversion state object -\end{itemize} - -\indexlibrarymember{state}{wbuffer_convert}% -\begin{itemdecl} -state_type state() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{cvtstate}. -\end{itemdescr} - -\indexlibrarymember{rdbuf}{wbuffer_convert}% -\begin{itemdecl} -streambuf* rdbuf() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{bufptr}. -\end{itemdescr} - -\indexlibrarymember{rdbuf}{wbuffer_convert}% -\begin{itemdecl} -streambuf* rdbuf(streambuf* bytebuf); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Stores \tcode{bytebuf} in \tcode{bufptr}. - -\pnum -\returns The previous value of \tcode{bufptr}. -\end{itemdescr} - -\indexlibrarymember{state_type}{wbuffer_convert}% -\begin{itemdecl} -using state_type = typename Codecvt::state_type; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The type shall be a synonym for \tcode{Codecvt::state_type}. -\end{itemdescr} - -\indexlibrary{\idxcode{wbuffer_convert}!constructor}% -\begin{itemdecl} -explicit wbuffer_convert(streambuf* bytebuf = 0, - Codecvt* pcvt = new Codecvt, state_type state = state_type()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{pcvt != nullptr}. - -\pnum -\effects The constructor constructs a stream buffer object, initializes -\tcode{bufptr} to \tcode{bytebuf}, initializes \tcode{cvtptr} -to \tcode{pcvt}, and initializes \tcode{cvtstate} to \tcode{state}. -\end{itemdescr} - -\indexlibrary{\idxcode{wbuffer_convert}!destructor}% -\begin{itemdecl} -~wbuffer_convert(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects The destructor shall delete \tcode{cvtptr}. -\end{itemdescr} - \rSec1[locale.categories]{Standard \tcode{locale} categories} \pnum @@ -1548,7 +1148,7 @@ static locale::id id; protected: - ~ctype(); + ~ctype(); virtual bool do_is(mask m, charT c) const; virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const; virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const; @@ -1931,7 +1531,7 @@ explicit ctype_byname(const char*, size_t refs = 0); explicit ctype_byname(const string&, size_t refs = 0); protected: - ~ctype_byname(); + ~ctype_byname(); }; } \end{codeblock} @@ -1974,7 +1574,7 @@ static const mask* classic_table() noexcept; protected: - ~ctype(); + ~ctype(); virtual char do_toupper(char c) const; virtual const char* do_toupper(char* low, const char* high) const; virtual char do_tolower(char c) const; @@ -2699,7 +2299,7 @@ value \tcode{state}. The specialization -\tcode{codecvt\colcol{}do_max_length()} +\tcode{codecvt::do_max_length()} returns 1. \end{itemdescr} @@ -2833,7 +2433,7 @@ }; } \end{codeblock} - + \pnum The facet \tcode{num_get} @@ -3360,7 +2960,7 @@ \tcode{!uppercase} & \tcode{\%g} \\ \rowsep \textit{otherwise} & \tcode{\%G} \\ \end{floattable} - + For conversions from an integral or floating-point type a length modifier is added to the conversion specifier as indicated in Table~\ref{tab:localization.length.modifier.out}. @@ -3395,12 +2995,12 @@ \tcode{str.precision()} is specified as precision in the conversion specification. Otherwise, no precision is specified. - + For conversion from \tcode{void*} the specifier is \tcode{\%p}. - + The representations at the end of stage 1 consists of the \tcode{char}'s that would be printed by a call of @@ -3417,14 +3017,14 @@ \begin{codeblock} const numpunct& punct = use_facet>(str.getloc()); \end{codeblock} - + For arithmetic types, \tcode{punct.thousands_sep()} characters are inserted into the sequence as determined by the value returned by \tcode{punct.do_grouping()} using the method described in~\ref{facet.numpunct.virtuals} - + Decimal point characters(.) are replaced by \tcode{punct.decimal_point()} @@ -3434,7 +3034,7 @@ \begin{codeblock} fmtflags adjustfield = (flags & (ios_base::adjustfield)); \end{codeblock} - + The location of any padding\footnote{The conversion specification \tcode{\#o} generates a leading @@ -3465,7 +3065,7 @@ then enough \tcode{fill} characters are added to the sequence at the position indicated for padding to bring the length of the sequence to \tcode{str.width()}. - + \tcode{str.width(0)} is called. @@ -3536,7 +3136,7 @@ static locale::id id; protected: - ~numpunct(); // virtual + ~numpunct(); // virtual virtual char_type do_decimal_point() const; virtual char_type do_thousands_sep() const; virtual string do_grouping() const; @@ -3744,7 +3344,7 @@ explicit numpunct_byname(const char*, size_t refs = 0); explicit numpunct_byname(const string&, size_t refs = 0); protected: - ~numpunct_byname(); + ~numpunct_byname(); }; } \end{codeblock} @@ -5385,7 +4985,7 @@ \tcode{get()} to retrieve a message from the message catalog identified by the string \tcode{name} according to an \impldef{mapping from name to catalog when calling -\tcode{mes\-sages\colcol{}do_open}} mapping. +\tcode{mes\-sages::do_open}} mapping. The result can be used until it is passed to \tcode{close()}. @@ -5626,7 +5226,6 @@ wchar_t c = use_facet(loc).widen('!'); if (!use_facet(loc).is_kanji(c)) cout << "no it isn't!" << endl; - return 0; } \end{codeblock} @@ -5667,118 +5266,10 @@ locale loc(locale(""), new My::BoolNames("")); cout.imbue(loc); cout << boolalpha << "Any arguments today? " << (argc > 1) << endl; - return 0; } \end{codeblock} \end{example} -\rSec1[locale.stdcvt]{Standard code conversion facets} - -\rSec2[codecvt.syn]{Header \tcode{} synopsis} - -\indexlibrary{\idxcode{codecvt}}% -\begin{codeblock} -namespace std { - enum codecvt_mode { - consume_header = 4, - generate_header = 2, - little_endian = 1 - }; - - template - class codecvt_utf8 : public codecvt { - public: - explicit codecvt_utf8(size_t refs = 0); - ~codecvt_utf8(); - }; - - template - class codecvt_utf16 : public codecvt { - public: - explicit codecvt_utf16(size_t refs = 0); - ~codecvt_utf16(); - }; - - template - class codecvt_utf8_utf16 : public codecvt { - public: - explicit codecvt_utf8_utf16(size_t refs = 0); - ~codecvt_utf8_utf16(); - }; -} -\end{codeblock} - -\pnum -The header \tcode{} provides code conversion facets for various character encodings. - -\rSec2[locale.stdcvt.req]{Requirements} - -\pnum -For each of the three code conversion facets \tcode{codecvt_utf8}, -\tcode{codecvt_utf16}, and \tcode{codecvt_utf8_utf16}: -\begin{itemize} -\item - \tcode{Elem} is the wide-character type, such as - \tcode{wchar_t}, \tcode{char16_t}, or \tcode{char32_t}. -\item - \tcode{Maxcode} is the largest wide-character code that the facet - will read or write without reporting a conversion error. -\item - If \tcode{(Mode \& consume_header)}, the facet shall consume an - initial header sequence, if present, when reading a multibyte sequence - to determine the endianness of the subsequent multibyte sequence to be read. -\item - If \tcode{(Mode \& generate_header)}, the facet shall generate an - initial header sequence when writing a multibyte sequence to advertise - the endianness of the subsequent multibyte sequence to be written. -\item - If \tcode{(Mode \& little_endian)}, the facet shall generate a - multibyte sequence in little-endian order, - as opposed to the default big-endian order. -\end{itemize} - -\pnum -For the facet \tcode{codecvt_utf8}: -\begin{itemize} -\item - The facet shall convert between UTF-8 multibyte sequences - and UCS2 or UCS4 (depending on the size of \tcode{Elem}) - within the program. -\item - Endianness shall not affect how multibyte sequences are read or written. -\item - The multibyte sequences may be written as either a text or a binary file. -\end{itemize} - -\pnum -For the facet \tcode{codecvt_utf16}: -\begin{itemize} -\item - The facet shall convert between UTF-16 multibyte sequences - and UCS2 or UCS4 (depending on the size of \tcode{Elem}) - within the program. -\item - Multibyte sequences shall be read or written - according to the \tcode{Mode} flag, as set out above. -\item - The multibyte sequences may be written only as a binary file. - Attempting to write to a text file produces undefined behavior. -\end{itemize} - -\pnum -For the facet \tcode{codecvt_utf8_utf16}: -\begin{itemize} -\item - The facet shall convert between UTF-8 multibyte sequences - and UTF-16 (one or two 16-bit codes) within the program. -\item - Endianness shall not affect how multibyte sequences are read or written. -\item - The multibyte sequences may be written as either a text or a binary file. -\end{itemize} - -\xref ISO/IEC 10646-1:1993. - \rSec1[c.locales]{C library locales} \rSec2[clocale.syn]{Header \tcode{} synopsis} diff --git a/source/macros.tex b/source/macros.tex index 959025812e..59dca332d1 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -48,14 +48,22 @@ } \makeatother +%%-------------------------------------------------- +% Escaping for index entries. Replaces ! with "! throughout its argument. +\def\indexescape#1{\doindexescape#1\stopindexescape!\doneindexescape} +\def\doindexescape#1!{#1"!\doindexescape} +\def\stopindexescape#1\doneindexescape{} + %%-------------------------------------------------- %% Cross references. -\newcommand{\addxref}[1]{\glossary[xrefindex]{#1}{(\ref{#1})}} +\newcommand{\addxref}[1]{% + \glossary[xrefindex]{\indexescape{#1}}{(\ref{\indexescape{#1}})}% +} %%-------------------------------------------------- -%% Sectioning macros. -% Each section has a depth, an automatically generated section -% number, a name, and a short tag. The depth is an integer in +%% Sectioning macros. +% Each section has a depth, an automatically generated section +% number, a name, and a short tag. The depth is an integer in % the range [0,5]. (If it proves necessary, it wouldn't take much % programming to raise the limit from 5 to something larger.) @@ -76,7 +84,7 @@ % A convenience feature (mostly for the convenience of the Project % Editor, to make it easy to move around large blocks of text): -% the \rSec macro is just like the \Sec macro, except that depths +% the \rSec macro is just like the \Sec macro, except that depths % relative to a global variable, SectionDepthBase. So, for example, % if SectionDepthBase is 1, % \rSec1[temp.arg.type]{Template type arguments} @@ -99,7 +107,7 @@ \newcommand{\indexgram}[1]{\index[grammarindex]{#1}} % Collation helper: When building an index key, replace all macro definitions -% in the key argument with a no-op for purposes of collation. +% in the key argument with a no-op for purposes of collation. \newcommand{\nocode}[1]{#1} \newcommand{\idxmname}[1]{\_\_#1\_\_} \newcommand{\idxCpp}{C++} @@ -167,8 +175,6 @@ %%-------------------------------------------------- %% allow line break if needed for justification \newcommand{\brk}{\discretionary{}{}{}} -% especially for scope qualifier -\newcommand{\colcol}{\brk::\brk} %%-------------------------------------------------- %% Macros for funky text @@ -324,8 +330,8 @@ keepspaces=true, texcl=true} -% Our usual abbreviation for 'listings'. Comments are in -% italics. Arbitrary TeX commands can be used if they're +% Our usual abbreviation for 'listings'. Comments are in +% italics. Arbitrary TeX commands can be used if they're % surrounded by @ signs. \newcommand{\CodeBlockSetup}{ \lstset{escapechar=@, aboveskip=\parskip, belowskip=0pt} @@ -510,16 +516,13 @@ } %%-------------------------------------------------- -%% Definitions section -% usage: \definition{name}{xref} -%\newcommand{\definition}[2]{\rSec2[#2]{#1}} -% for ISO format, use: -\newcommand{\definition}[2]{% -\addxref{#2}% -\subsection[#1]{\hfill[#2]}\vspace{-.3\onelineskip}\label{#2}\textbf{#1}\\% -} -\newcommand{\definitionx}[2]{% -\addxref{#2}% -\subsubsection[#1]{\hfill[#2]}\vspace{-.3\onelineskip}\label{#2}\textbf{#1}\\% +%% Definitions section for "Terms and definitions" +\newcommand{\nocontentsline}[3]{} +\newcommand{\definitionx}[3]{% +\addxref{#3}% +\let\oldcontentsline\addcontentsline% +\let\addcontentsline\nocontentsline% +#1[#2]{\hfill[#3]}\vspace{-.3\onelineskip}\label{#3} \textbf{#2}\\*% +\let\addcontentsline\oldcontentsline% } \newcommand{\defncontext}[1]{\textlangle#1\textrangle} diff --git a/source/numerics.tex b/source/numerics.tex index 2bc129b2e0..d6b313c1db 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -25,29 +25,28 @@ \ref{numarray} & Numeric arrays & \tcode{} \\ \rowsep \ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep \ref{c.math} & Mathematical functions for & \tcode{} \\ - & floating-point types & \tcode{} \\ - & & \tcode{} \\ + & floating-point types & \tcode{} \\ \end{libsumtab} \rSec1[numerics.defns]{Definitions} -\indexlibrary{generalized_noncommutative_sum@\tcode{\textit{GENERALIZED_NONCOMMUTATIVE_SUM}}}% +\indexlibrary{generalized_noncommutative_sum@\tcode{\placeholder{GENERALIZED_NONCOMMUTATIVE_SUM}}}% \pnum -Define \tcode{\textit{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aN)} as follows: +Define \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aN)} as follows: \begin{itemize} \item \tcode{a1} when \tcode{N} is \tcode{1}, otherwise \item -\tcode{op(\textit{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aK),} \\ -\tcode{\phantom{op(}\textit{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, ..., aN))} +\tcode{op(\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aK),} \\ +\tcode{\phantom{op(}\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, ..., aN))} for any \tcode{K} where $1 < \mathtt{K}+1 = \mathtt{M} \leq \mathtt{N}$. \end{itemize} -\indexlibrary{generalized_sum@\tcode{\textit{GENERALIZED_SUM}}}% +\indexlibrary{generalized_sum@\tcode{\placeholder{GENERALIZED_SUM}}}% \pnum -Define \tcode{\textit{GENERALIZED_SUM}(op, a1, ..., aN)} as -\tcode{\textit{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, ..., bN)} +Define \tcode{\placeholdernc{GENERALIZED_SUM}(op, a1, ..., aN)} as +\tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, ..., bN)}, where \tcode{b1, ..., bN} may be any permutation of \tcode{a1, ..., aN}. @@ -1281,9 +1280,9 @@ \indexlibrary{\idxcode{real}}% The following function templates shall have additional overloads: \begin{codeblock} -arg norm +arg norm conj proj -imag real +imag real \end{codeblock} \pnum @@ -1291,11 +1290,11 @@ The additional overloads shall be sufficient to ensure: \begin{enumerate} - \item If the argument has type \tcode{long double}, then it is effectively + \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 + \item Otherwise, if the argument has type \tcode{float}, then it is effectively cast to \tcode{complex}. \end{enumerate} @@ -1327,7 +1326,7 @@ \tcode{complex} respectively, with their imaginary part denoted by the given literal number and the real part being zero. -\indexlibrarymember{operator """" il}{complex}% +\indexlibrarymember{operator""""il}{complex}% \begin{itemdecl} constexpr complex operator""il(long double d); constexpr complex operator""il(unsigned long long d); @@ -1339,7 +1338,7 @@ \tcode{complex\{0.0L, static_cast(d)\}}. \end{itemdescr} -\indexlibrarymember{operator """" i}{complex}% +\indexlibrarymember{operator""""i}{complex}% \begin{itemdecl} constexpr complex operator""i(long double d); constexpr complex operator""i(unsigned long long d); @@ -1351,7 +1350,7 @@ \tcode{complex\{0.0, static_cast(d)\}}. \end{itemdescr} -\indexlibrarymember{operator """" if}{complex}% +\indexlibrarymember{operator""""if}{complex}% \begin{itemdecl} constexpr complex operator""if(long double d); constexpr complex operator""if(unsigned long long d); @@ -1363,18 +1362,6 @@ \tcode{complex\{0.0f, static_cast(d)\}}. \end{itemdescr} -\rSec2[ccomplex.syn]{Header \tcode{} synopsis} -\indextext{\idxhdr{ccomplex}}% -\indexlibrary{\idxhdr{ccomplex}}% - -\begin{codeblock} -#include -\end{codeblock} - -\pnum -The header \tcode{} -behaves as if it simply includes the header \tcode{}. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1439,7 +1426,7 @@ \item otherwise as \techterm{integral} or equivalently as \techterm{integer-valued}, - if \tcode{numeric_limits\colcol{}is_integer} is \tcode{true}; + if \tcode{numeric_limits::is_integer} is \tcode{true}; \item otherwise as \techterm{floating} or equivalently as \techterm{real-valued}. @@ -1527,7 +1514,7 @@ is undefined unless the corresponding template argument is cv-unqualified and is one of - \tcode{float}, \tcode{double}, or \tcode{long} \tcode{double}. + \tcode{float}, \tcode{double}, or \tcode{long double}. \item that has a template type parameter named \tcode{IntType} @@ -1537,23 +1524,23 @@ \tcode{short}, \tcode{int}, \tcode{long}, - \tcode{long} \tcode{long}, - \tcode{unsigned} \tcode{short}, - \tcode{unsigned} \tcode{int}, - \tcode{unsigned} \tcode{long}, + \tcode{long long}, + \tcode{unsigned short}, + \tcode{unsigned int}, + \tcode{unsigned long}, or - \tcode{unsigned} \tcode{long} \tcode{long}. + \tcode{unsigned long long}. \item that has a template type parameter named \tcode{UIntType} is undefined unless the corresponding template argument is cv-unqualified and is one of - \tcode{unsigned} \tcode{short}, - \tcode{unsigned} \tcode{int}, - \tcode{unsigned} \tcode{long}, + \tcode{unsigned short}, + \tcode{unsigned int}, + \tcode{unsigned long}, or - \tcode{unsigned} \tcode{long} \tcode{long}. + \tcode{unsigned long long}. \end{enumeratea} \pnum @@ -2023,7 +2010,7 @@ \indextext{\idxcode{operator<<}!random number engine requirement} & reference to the type of \tcode{os} & With \tcode{os.}\textit{fmtflags} set to - \tcode{ios_base\colcol{}dec|ios_base\colcol{}left} + \tcode{ios_base::dec|ios_base::left} and the fill character set to the space character, writes to \tcode{os} the textual representation @@ -2046,7 +2033,7 @@ ensures that \tcode{v}'s state is unchanged by the operation and calls \tcode{is.setstate(ios::failbit)} - (which may throw \tcode{ios::failure}~[\ref{iostate.flags}]). + (which may throw \tcode{ios::failure}~(\ref{iostate.flags})). If a textual representation written via \tcode{os << x} was subsequently read via \tcode{is >> v}, then \tcode{x == v} @@ -2128,7 +2115,7 @@ \begin{itemdecl} -A::A(result_type s); +A::A(result_type s); \end{itemdecl} \begin{itemdescr} @@ -2149,7 +2136,7 @@ \end{itemdescr} \begin{itemdecl} -void seed(); +void seed(); \end{itemdecl} \begin{itemdescr} @@ -2158,7 +2145,7 @@ \end{itemdescr} \begin{itemdecl} -void seed(result_type s); +void seed(result_type s); \end{itemdecl} \begin{itemdescr} @@ -2167,7 +2154,7 @@ \end{itemdescr} \begin{itemdecl} -template void seed(Sseq& q); +template void seed(Sseq& q); \end{itemdecl} \begin{itemdescr} @@ -2432,8 +2419,8 @@ If bad input is encountered, ensures that \tcode{d} is unchanged by the operation and - calls \tcode{is.setstate(ios\colcol{}failbit)} - (which may throw \tcode{ios\colcol{}failure}~[\ref{iostate.flags}]). + calls \tcode{is.setstate(ios::failbit)} + (which may throw \tcode{ios::failure}~(\ref{iostate.flags})). \requires \tcode{is} provides a textual representation that was previously written @@ -2527,30 +2514,30 @@ #include namespace std { - // \ref{rand.eng.lcong}, class template linear_congruential_engine + // \ref{rand.eng.lcong}, class template \tcode{linear_congruential_engine} template class linear_congruential_engine; - // \ref{rand.eng.mers}, class template mersenne_twister_engine + // \ref{rand.eng.mers}, class template \tcode{mersenne_twister_engine} template class mersenne_twister_engine; - // \ref{rand.eng.sub}, class template subtract_with_carry_engine + // \ref{rand.eng.sub}, class template \tcode{subtract_with_carry_engine} template class subtract_with_carry_engine; - // \ref{rand.adapt.disc}, class template discard_block_engine + // \ref{rand.adapt.disc}, class template \tcode{discard_block_engine} template class discard_block_engine; - // \ref{rand.adapt.ibits}, class template independent_bits_engine + // \ref{rand.adapt.ibits}, class template \tcode{independent_bits_engine} template class independent_bits_engine; - // \ref{rand.adapt.shuf}, class template shuffle_order_engine + // \ref{rand.adapt.shuf}, class template \tcode{shuffle_order_engine} template class shuffle_order_engine; @@ -2567,92 +2554,92 @@ using default_random_engine = @\seebelow@; - // \ref{rand.device}, class random_device + // \ref{rand.device}, class \tcode{random_device} class random_device; - // \ref{rand.util.seedseq}, class seed_seq + // \ref{rand.util.seedseq}, class \tcode{seed_seq} class seed_seq; - // \ref{rand.util.canonical}, function template generate_canonical + // \ref{rand.util.canonical}, function template \tcode{generate_canonical} template RealType generate_canonical(URBG& g); - // \ref{rand.dist.uni.int}, class template uniform_int_distribution + // \ref{rand.dist.uni.int}, class template \tcode{uniform_int_distribution} template class uniform_int_distribution; - // \ref{rand.dist.uni.real}, class template uniform_real_distribution + // \ref{rand.dist.uni.real}, class template \tcode{uniform_real_distribution} template class uniform_real_distribution; - // \ref{rand.dist.bern.bernoulli}, class bernoulli_distribution + // \ref{rand.dist.bern.bernoulli}, class \tcode{bernoulli_distribution} class bernoulli_distribution; - // \ref{rand.dist.bern.bin}, class template binomial_distribution + // \ref{rand.dist.bern.bin}, class template \tcode{binomial_distribution} template class binomial_distribution; - // \ref{rand.dist.bern.geo}, class template geometric_distribution + // \ref{rand.dist.bern.geo}, class template \tcode{geometric_distribution} template class geometric_distribution; - // \ref{rand.dist.bern.negbin}, class template negative_binomial_distribution + // \ref{rand.dist.bern.negbin}, class template \tcode{negative_binomial_distribution} template class negative_binomial_distribution; - // \ref{rand.dist.pois.poisson}, class template poisson_distribution + // \ref{rand.dist.pois.poisson}, class template \tcode{poisson_distribution} template class poisson_distribution; - // \ref{rand.dist.pois.exp}, class template exponential_distribution + // \ref{rand.dist.pois.exp}, class template \tcode{exponential_distribution} template class exponential_distribution; - // \ref{rand.dist.pois.gamma}, class template gamma_distribution + // \ref{rand.dist.pois.gamma}, class template \tcode{gamma_distribution} template class gamma_distribution; - // \ref{rand.dist.pois.weibull}, class template weibull_distribution + // \ref{rand.dist.pois.weibull}, class template \tcode{weibull_distribution} template class weibull_distribution; - // \ref{rand.dist.pois.extreme}, class template extreme_value_distribution + // \ref{rand.dist.pois.extreme}, class template \tcode{extreme_value_distribution} template class extreme_value_distribution; - // \ref{rand.dist.norm.normal}, class template normal_distribution + // \ref{rand.dist.norm.normal}, class template \tcode{normal_distribution} template class normal_distribution; - // \ref{rand.dist.norm.lognormal}, class template lognormal_distribution + // \ref{rand.dist.norm.lognormal}, class template \tcode{lognormal_distribution} template class lognormal_distribution; - // \ref{rand.dist.norm.chisq}, class template chi_squared_distribution + // \ref{rand.dist.norm.chisq}, class template \tcode{chi_squared_distribution} template class chi_squared_distribution; - // \ref{rand.dist.norm.cauchy}, class template cauchy_distribution + // \ref{rand.dist.norm.cauchy}, class template \tcode{cauchy_distribution} template class cauchy_distribution; - // \ref{rand.dist.norm.f}, class template fisher_f_distribution + // \ref{rand.dist.norm.f}, class template \tcode{fisher_f_distribution} template class fisher_f_distribution; - // \ref{rand.dist.norm.t}, class template student_t_distribution + // \ref{rand.dist.norm.t}, class template \tcode{student_t_distribution} template class student_t_distribution; - // \ref{rand.dist.samp.discrete}, class template discrete_distribution + // \ref{rand.dist.samp.discrete}, class template \tcode{discrete_distribution} template class discrete_distribution; - // \ref{rand.dist.samp.pconst}, class template piecewise_constant_distribution + // \ref{rand.dist.samp.pconst}, class template \tcode{piecewise_constant_distribution} template class piecewise_constant_distribution; - // \ref{rand.dist.samp.plinear}, class template piecewise_linear_distribution + // \ref{rand.dist.samp.plinear}, class template \tcode{piecewise_linear_distribution} template class piecewise_linear_distribution; } @@ -2805,7 +2792,7 @@ the modulus $m$ used throughout this section~\ref{rand.eng.lcong} \indextext{\idxcode{linear_congruential_engine}!modulus} -is \tcode{numeric_limits\colcol{}max()} plus $1$. +is \tcode{numeric_limits::max()} plus $1$. \begin{note} $m$ need not be representable as a value of type \tcode{result_type}. @@ -4206,7 +4193,7 @@ to avoid any attempt to produce more bits of randomness than can be held in \tcode{RealType}.} - is the lesser of \tcode{numeric_limits\colcol{}digits} + is the lesser of \tcode{numeric_limits::digits} and \tcode{bits}, and $R$ is the value of $ \tcode{g.max()} - \tcode{g.min()} + 1 $. @@ -4432,7 +4419,7 @@ \pnum\requires $ \tcode{a} \leq \tcode{b} $ and - $ \tcode{b} - \tcode{a} \leq \tcode{numeric_limits\colcol{}max()} $. + $ \tcode{b} - \tcode{a} \leq \tcode{numeric_limits::max()} $. \pnum\effects Constructs a \tcode{uniform_real_distribution} object; \tcode{a} and \tcode{b} @@ -4776,7 +4763,7 @@ correspond to the respective parameters of the distribution. \end{itemdescr} -\indexlibrarymember{t}{negative_binomial_distribution}% +\indexlibrarymember{k}{negative_binomial_distribution}% \begin{itemdecl} IntType k() const; \end{itemdecl} @@ -6737,6 +6724,8 @@ valarray apply(T func(const T&)) const; void resize(size_t sz, T c = T()); }; + + template valarray(const T(&)[cnt], size_t) -> valarray; } \end{codeblock} @@ -8273,7 +8262,7 @@ void operator>>=(const valarray&) const; mask_array(const mask_array&); - ~mask_array(); + ~mask_array(); const mask_array& operator=(const mask_array&) const; void operator=(const T&) const; @@ -8398,7 +8387,7 @@ void operator>>=(const valarray&) const; indirect_array(const indirect_array&); - ~indirect_array(); + ~indirect_array(); const indirect_array& operator=(const indirect_array&) const; void operator=(const T&) const; @@ -8579,12 +8568,14 @@ \indexlibrary{\idxhdr{numeric}}% \begin{codeblock} namespace std { + // \ref{accumulate}, accumulate template T accumulate(InputIterator first, InputIterator last, T init); template T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); + // \ref{reduce}, reduce template typename iterator_traits::value_type reduce(InputIterator first, InputIterator last); @@ -8593,27 +8584,19 @@ template T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); - template - typename iterator_traits::value_type + template + typename iterator_traits::value_type reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last); - template + ForwardIterator first, ForwardIterator last); + template T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, T init); - template + ForwardIterator first, ForwardIterator last, T init); + template T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, T init, + ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); - template - T transform_reduce(InputIterator first, InputIterator last, - UnaryOperation unary_op, T init, BinaryOperation binary_op); - template - T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - UnaryOperation unary_op, T init, BinaryOperation binary_op); - + // \ref{inner.product}, inner product template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); @@ -8623,19 +8606,48 @@ InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); - template - T inner_product(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init); - template - T inner_product(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, - BinaryOperation1 binary_op1, - BinaryOperation2 binary_op2); + // \ref{transform.reduce}, transform reduce + template + T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init); + template + T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); + template + T transform_reduce(InputIterator first, InputIterator last, + T init, + BinaryOperation binary_op, UnaryOperation unary_op); + template + T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init); + template + T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); + template + T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + T init, + BinaryOperation binary_op, UnaryOperation unary_op); + + // \ref{partial.sum}, partial sum template OutputIterator partial_sum(InputIterator first, InputIterator last, @@ -8646,6 +8658,7 @@ OutputIterator result, BinaryOperation binary_op); + // \ref{exclusive.scan}, exclusive scan template OutputIterator exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, @@ -8654,17 +8667,19 @@ OutputIterator exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init, BinaryOperation binary_op); - template - OutputIterator exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - T init); - template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init); + template - OutputIterator exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - T init, BinaryOperation binary_op); + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init, BinaryOperation binary_op); + + // \ref{inclusive.scan}, inclusive scan template OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result); @@ -8676,69 +8691,74 @@ OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, T init); - template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result); - template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op); - template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op, T init); - - template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, T init); + + // \ref{transform.exclusive.scan}, transform exclusive scan + template OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, - UnaryOperation unary_op, - T init, BinaryOperation binary_op); - template - OutputIterator transform_exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - T init, BinaryOperation binary_op); + T init, + BinaryOperation binary_op, + UnaryOperation unary_op); + template + ForwardIterator2 transform_exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init, + BinaryOperation binary_op, + UnaryOperation unary_op); + + // \ref{transform.inclusive.scan}, transform inclusive scan template - OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op); + class BinaryOperation, class UnaryOperation> + OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, + UnaryOperation unary_op); template - OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op, T init); - template - OutputIterator transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op); - template - OutputIterator transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op, T init); - + class BinaryOperation, class UnaryOperation, class T> + OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, + UnaryOperation unary_op, + T init); + template + ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, + UnaryOperation unary_op); + template + ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, + UnaryOperation unary_op, + T init); + + // \ref{adjacent.difference}, adjacent difference template OutputIterator adjacent_difference(InputIterator first, InputIterator last, @@ -8748,19 +8768,20 @@ InputIterator last, OutputIterator result, BinaryOperation binary_op); - template - OutputIterator adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, - InputIterator last, - OutputIterator result); - template + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, + ForwardIterator1 last, + ForwardIterator2 result); + template - OutputIterator adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, - InputIterator last, - OutputIterator result, - BinaryOperation binary_op); + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, + ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op); + // \ref{numeric.iota}, iota template void iota(ForwardIterator first, ForwardIterator last, T value); @@ -8779,6 +8800,21 @@ described in the introduction to Clause~\ref{algorithms} also apply to the following algorithms. +\pnum +Throughout this subclause, the parameters +\tcode{UnaryOperation}, +\tcode{BinaryOperation}, +\tcode{BinaryOperation1}, +and \tcode{BinaryOperation2} +are used +whenever an algorithm expects a function object~(\ref{function.objects}). + +\pnum +\begin{note} +The use of closed ranges as well as semi-open ranges to specify requirements +throughout this subclause is intentional. +\end{note} + \rSec2[accumulate]{Accumulate} \indexlibrary{\idxcode{accumulate}}% @@ -8839,10 +8875,10 @@ \indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - typename iterator_traits::value_type +template + typename iterator_traits::value_type reduce(ExecutionPolicy&& exec, - InputIterator first, InputIterator last); + ForwardIterator first, ForwardIterator last); \end{itemdecl} \begin{itemdescr} @@ -8850,7 +8886,7 @@ \effects Equivalent to: \begin{codeblock} return reduce(std::forward(exec), first, last, - typename iterator_traits::value_type{}); + typename iterator_traits::value_type{}); \end{codeblock} \end{itemdescr} @@ -8871,9 +8907,9 @@ \indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template +template T reduce(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, T init); + ForwardIterator first, ForwardIterator last, T init); \end{itemdecl} \begin{itemdescr} @@ -8890,21 +8926,27 @@ template T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); -template +template T reduce(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, T init, + ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{binary_op} shall neither invalidate iterators or subranges, nor modify -elements in the range \range{first}{last}. +\begin{itemize} +\item \tcode{T} shall be \tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}). +\item All of \tcode{binary_op(init, *first)}, \tcode{binary_op(*first, init)}, +\tcode{binary_op(init, init)}, and \tcode{binary_op(*first, *first)} shall be +convertible to \tcode{T}. +\item \tcode{binary_op} shall neither invalidate iterators or subranges, nor modify +elements in the range \crange{first}{last}. +\end{itemize} \pnum \returns -\tcode{\textit{GENERALIZED_SUM}(binary_op, init, *i, ...)} for every \tcode{i} in \range{first}{last}. +\tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, ...)} for every \tcode{i} in \range{first}{last}. \pnum \complexity @@ -8919,41 +8961,6 @@ \end{note} \end{itemdescr} -\rSec2[transform.reduce]{Transform reduce} - -\indexlibrary{\idxcode{transform_reduce}}% -\begin{itemdecl} -template - T transform_reduce(InputIterator first, InputIterator last, - UnaryOperation unary_op, T init, BinaryOperation binary_op); -template - T transform_reduce(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - UnaryOperation unary_op, T init, BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate subranges, or -modify elements in the range \range{first}{last}. - -\pnum -\returns -\tcode{\textit{GENERALIZED_SUM}(binary_op, init, unary_op(*i), ...)} for every \tcode{i} in \range{first}{last}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and -\tcode{binary_op}. - -\pnum -\begin{note} -\tcode{transform_reduce} does not apply \tcode{unary_op} to \tcode{init}. -\end{note} -\end{itemdescr} - \rSec2[inner.product]{Inner product} \indexlibrary{\idxcode{inner_product}}% @@ -8961,24 +8968,12 @@ template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); -template - T inner_product(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init); - template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); -template - T inner_product(ExecutionPolicy&& exec, - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, - BinaryOperation1 binary_op1, - BinaryOperation2 binary_op2); \end{itemdecl} \begin{itemdescr} @@ -9015,6 +9010,128 @@ in order. \end{itemdescr} +\rSec2[transform.reduce]{Transform reduce} +\indexlibrary{\idxcode{transform_reduce}}% +\begin{itemdecl} +template + T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return transform_reduce(first1, last1, first2, init, plus<>(), multiplies<>()); +\end{codeblock} +\end{itemdescr} + +\indexlibrary{\idxcode{transform_reduce}}% +\begin{itemdecl} +template + T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\begin{itemize} +\item \tcode{T} shall be \tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}). +\item All of +\begin{itemize} +\item \tcode{binary_op1(init, init)}, +\item \tcode{binary_op1(init, binary_op2(*first1, *first2))}, +\item \tcode{binary_op1(binary_op2(*first1, *first2), init)}, and +\item \tcode{binary_op1(binary_op2(*first1, *first2), binary_op2(*first1, *first2))} +\end{itemize} +shall be convertible to \tcode{T}. +\item Neither \tcode{binary_op1} nor \tcode{binary_op2} shall invalidate +subranges, or modify elements in the ranges \crange{first1}{last1} and +\crange{first2}{first2 + (last1 - first1)}. +\end{itemize} + +\pnum +\returns +\begin{codeblock} +@\placeholdernc{GENERALIZED_SUM}@(binary_op1, init, binary_op2(*i, *(first2 + (i - first1))), ...) +\end{codeblock} +for every iterator \tcode{i} in \range{first1}{last1}. + +\pnum +\complexity \bigoh{\tcode{last1 - first1}} applications each of \tcode{binary_op1} and +\tcode{binary_op2}. +\end{itemdescr} + +\indexlibrary{\idxcode{transform_reduce}}% +\begin{itemdecl} +template + T transform_reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op, UnaryOperation unary_op); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + T init, BinaryOperation binary_op, UnaryOperation unary_op); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\begin{itemize} +\item \tcode{T} shall be \tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}). +\item All of +\begin{itemize} +\item \tcode{binary_op(init, init)}, +\item \tcode{binary_op(init, unary_op(*first))}, +\item \tcode{binary_op(unary_op(*first), init)}, and +\item \tcode{binary_op(unary_op(*first), unary_op(*first))} +\end{itemize} +shall be convertible to \tcode{T}. +\item Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate subranges, +or modify elements in the range \crange{first}{last}. +\end{itemize} + +\pnum +\returns +\begin{codeblock} +@\placeholdernc{GENERALIZED_SUM}@(binary_op, init, unary_op(*i), ...) +\end{codeblock} +for every iterator \tcode{i} in \range{first}{last}. + +\pnum +\complexity +\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and +\tcode{binary_op}. + +\pnum +\begin{note} +\tcode{transform_reduce} does not apply \tcode{unary_op} to \tcode{init}. +\end{note} +\end{itemdescr} + \rSec2[partial.sum]{Partial sum} \indexlibrary{\idxcode{partial_sum}}% @@ -9090,11 +9207,11 @@ \indexlibrary{\idxcode{exclusive_scan}}% \begin{itemdecl} -template - OutputIterator exclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - T init); +template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init); \end{itemdecl} \begin{itemdescr} @@ -9114,19 +9231,23 @@ OutputIterator result, T init, BinaryOperation binary_op); template - OutputIterator exclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - T init, BinaryOperation binary_op); + class ForwardIterator1, class ForwardIterator2, class T, class BinaryOperation> + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{binary_op} shall neither invalidate iterators or subranges, nor modify -elements in the -ranges \range{first}{last} or \range{result}{result + (last - first)}. +\begin{itemize} +\item \tcode{T} shall be \tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}). +\item All of \tcode{binary_op(init, init)}, \tcode{binary_op(init, *first)}, +and \tcode{binary_op(*first, *first)} shall be convertible to \tcode{T}. +\item \tcode{binary_op} shall neither invalidate iterators or subranges, nor modify +elements in the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. +\end{itemize} \pnum \effects @@ -9177,10 +9298,10 @@ \indexlibrary{\idxcode{inclusive_scan}}% \begin{itemdecl} -template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result); +template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} @@ -9198,30 +9319,42 @@ OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); -template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op); +template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op); template OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, T init); template - OutputIterator inclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op, T init); + class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class T> + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, T init); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{binary_op} shall not invalidate iterators or subranges, nor modify -elements in the ranges \range{first}{last} or -\range{result}{result + (last - first)}. +\begin{itemize} +\item If \tcode{init} is provided, \tcode{T} shall be \tcode{MoveConstructible} +(Table~\ref{tab:moveconstructible}); otherwise, \tcode{ForwardIterator1}'s value +type shall be \tcode{MoveConstructible}. + +\item If \tcode{init} is provided, all of \tcode{binary_op(init, init)}, +\tcode{binary_op(init, *first)}, and \tcode{binary_op(*first, *first)} shall be +convertible to \tcode{T}; otherwise, \tcode{binary_op(*first, *first)} shall be +convertible to \tcode{ForwardIterator1}'s value type. + +\item \tcode{binary_op} shall neither invalidate iterators or subranges, nor +modify elements in the ranges \crange{first}{last} or +\crange{result}{result + (last - first)}. +\end{itemize} \pnum \effects @@ -9261,30 +9394,41 @@ \indexlibrary{\idxcode{transform_exclusive_scan}}% \begin{itemdecl} -template +template OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, - UnaryOperation unary_op, - T init, BinaryOperation binary_op); -template - OutputIterator transform_exclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - T init, BinaryOperation binary_op); + T init, + BinaryOperation binary_op, + UnaryOperation unary_op); +template + ForwardIterator2 transform_exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init, + BinaryOperation binary_op, + UnaryOperation unary_op); \end{itemdecl} \begin{itemdescr} \pnum \requires -Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate iterators or +\begin{itemize} +\item \tcode{T} shall be \tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}). +\item All of +\begin{itemize} +\item \tcode{binary_op(init, init)}, +\item \tcode{binary_op(init, unary_op(*first))}, and +\item \tcode{binary_op(unary_op(*first), unary_op(*first))} +\end{itemize} +shall be convertible to \tcode{T}. +\item Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate iterators or subranges, or modify elements in the ranges -\range{first}{last} or -\range{result}{result + (last - first)}. +\crange{first}{last} or +\crange{result}{result + (last - first)}. +\end{itemize} \pnum \effects @@ -9325,44 +9469,59 @@ \indexlibrary{\idxcode{transform_inclusive_scan}}% \begin{itemdecl} template + class BinaryOperation, class UnaryOperation> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op); -template - OutputIterator transform_inclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op); - + BinaryOperation binary_op, + UnaryOperation unary_op); +template + ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, + UnaryOperation unary_op); template + class BinaryOperation, class UnaryOperation, class T> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, + BinaryOperation binary_op, UnaryOperation unary_op, - BinaryOperation binary_op, T init); -template - OutputIterator transform_inclusive_scan(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, - UnaryOperation unary_op, - BinaryOperation binary_op, T init); + T init); +template + ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, + UnaryOperation unary_op, + T init); \end{itemdecl} \begin{itemdescr} \pnum \requires -Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate iterators or -subranges, or modify elements in the ranges \range{first}{last} or -\range{result}{result + (last - first)}. +\begin{itemize} +\item If \tcode{init} is provided, \tcode{T} shall be \tcode{MoveConstructible} +(Table~\ref{tab:moveconstructible}); otherwise, \tcode{ForwardIterator1}'s value +type shall be \tcode{MoveConstructible}. + +\item If \tcode{init} is provided, all of +\begin{itemize} +\item \tcode{binary_op(init, init)}, +\item \tcode{binary_op(init, unary_op(*first))}, and +\item \tcode{binary_op(unary_op(*first), unary_op(*first))} +\end{itemize} +shall be convertible to +\tcode{T}; otherwise, \tcode{binary_op(unary_op(*first), unary_op(*first))} +shall be convertible to \tcode{ForwardIterator1}'s value type. + +\item Neither \tcode{unary_op} nor \tcode{binary_op} shall invalidate iterators +or subranges, nor modify elements in the ranges \crange{first}{last} or +\crange{result}{result + (last - first)}. +\end{itemize} \pnum \effects @@ -9409,42 +9568,58 @@ OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); -template - OutputIterator +template + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result); + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); template OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); -template - OutputIterator +template + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, - InputIterator first, InputIterator last, - OutputIterator result, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{InputIterator}'s value type shall be \tcode{MoveAssignable} (Table~\ref{tab:moveassignable}) -and shall be constructible from the type of \tcode{*first}. \tcode{acc} shall be -writable~(\ref{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. -In the ranges +\begin{itemize} +\item +For the overloads with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s value +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~(\ref{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. + +\item +For the overloads with an \tcode{ExecutionPolicy}, the value type of +\tcode{ForwardIterator1} +shall be \tcode{CopyConstructible} (Table~\ref{tab:copyconstructible}), +constructible from the expression \tcode{*first - *first} or +\tcode{binary_op(*first, *first)}, and assignable to the value type of +\tcode{ForwardIterator2}. + +\item +For all overloads, in the ranges \crange{first}{last} and \crange{result}{result + (last - first)}, \tcode{binary_op} shall neither modify elements nor invalidate iterators or subranges.\footnote{The use of fully closed ranges is intentional.} +\end{itemize} \pnum -\effects For a non-empty range, +\effects For the overloads with no \tcode{ExecutionPolicy} and a non-empty range, the function creates an accumulator \tcode{acc} whose type is \tcode{InputIterator}'s value type, initializes it with \tcode{*first}, and assigns the result to \tcode{*result}. For every iterator \tcode{i} in \range{first + 1}{last} @@ -9452,6 +9627,17 @@ with \tcode{*i}, computes \tcode{val - acc} or \tcode{binary_op(val, acc)}, assigns the result to \tcode{*(result + (i - first))}, and move assigns from \tcode{val} to \tcode{acc}. +\pnum +For the overloads with an \tcode{ExecutionPolicy} and a non-empty range, first the +function creates an object whose type is \tcode{ForwardIterator1}'s value type, +initializes it with \tcode{*first}, and assigns the result to \tcode{*result}. +Then for every \tcode{d} +in \crange{1}{last - first - 1}, creates an object \tcode{val} whose type is +\tcode{ForwardIterator1}'s value type, initializes it with +\tcode{*(first + d) - *(first + d - 1)} or +\tcode{binary_op(*(first + d), *(first + d - 1))}, and assigns the result to +\tcode{*(result + d)}. + \pnum \returns \tcode{result + (last - first)}. @@ -9465,9 +9651,9 @@ \pnum \remarks -\tcode{result} -may be equal to -\tcode{first}. +For the overloads with no \tcode{ExecutionPolicy}, \tcode{result} may be equal +to \tcode{first}. For the overloads with an \tcode{ExecutionPolicy}, the ranges +\range{first}{last} and \range{result}{result + (last - first)} shall not overlap. \end{itemdescr} \rSec2[numeric.iota]{Iota} @@ -9504,8 +9690,8 @@ \begin{itemdescr} \pnum \requires -\tcode{|m|} shall be representable as a value of type \tcode{M} and -\tcode{|n|} shall be representable as a value of type \tcode{N}. +\tcode{|m|} and \tcode{|n|} shall +be representable as a value of \tcode{common_type_t}. \begin{note} These requirements ensure, for example, that \tcode{gcd(m, m) = |m|} is representable as a value of type \tcode{M}. \end{note} @@ -9535,8 +9721,8 @@ \begin{itemdescr} \pnum \requires -\tcode{|m|} shall be representable as a value of type \tcode{M} and -\tcode{|n|} shall be representable as a value of type \tcode{N}. +\tcode{|m|} and \tcode{|n|} shall +be representable as a value of \tcode{common_type_t}. The least common multiple of \tcode{|m|} and \tcode{|n|} shall be representable as a value of type \tcode{common_type_t}. @@ -10309,7 +10495,7 @@ \pnum The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}, -with the addition of +with the addition of a three-dimensional hypotenuse function~(\ref{c.math.hypot3}) and the mathematical special functions described in \ref{sf.cmath}. \begin{note} @@ -11261,21 +11447,3 @@ \end{itemdescr} \indextext{mathematical special functions|)} - -\rSec2[ctgmath.syn]{Header \tcode{} synopsis} - -\indextext{\idxhdr{ctgmath}}% -\indexlibrary{\idxhdr{ctgmath}}% -\begin{codeblock} -#include -#include -\end{codeblock} - -\pnum -The header \tcode{} simply includes the headers \tcode{} -and \tcode{}. - -\pnum -\begin{note} The overloads provided in C by type-generic macros are already -provided in \tcode{} and \tcode{} by ``sufficient'' additional -overloads.\end{note} diff --git a/source/overloading.tex b/source/overloading.tex index 3c2bdc82af..58059376e4 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -10,7 +10,7 @@ \indextext{function, overloaded|see{overloading}}% When two or more different declarations are specified for a single name in the same scope, that name is said to be -\grammarterm{overloaded}. +\defnx{overloaded}{overloading}. By extension, two declarations in the same scope that declare the same name but with different types are called \term{overloaded declarations}. @@ -1392,8 +1392,9 @@ \begin{itemize} \item For each constructor -of the class template +of the primary class template designated by the \grammarterm{template-name}, +if the template is defined, a function template with the following properties: \begin{itemize} \item @@ -1411,6 +1412,17 @@ obtained from the class template. \end{itemize} +\item +If the primary class template \tcode{C} +is not defined or does not declare any constructors, +an additional function template derived as above +from a hypothetical constructor \tcode{C()}. + +\item +An additional function template derived as above +from a hypothetical constructor \tcode{C(C)}, +called the \defn{copy deduction candidate}. + \item For each \grammarterm{deduction-guide}, a function or function template @@ -1440,6 +1452,8 @@ is considered to be explicit if the function or function template was generated from a constructor or \grammarterm{deduction-guide} that was declared \tcode{explicit}. +All such notional constructors are considered to be +public members of the hypothetical class type. \pnum \begin{example} @@ -1640,26 +1654,6 @@ \end{example} or, if not that, -\item -\tcode{F1} is generated from a -\grammarterm{deduction-guide}~(\ref{over.match.class.deduct}) -and \tcode{F2} is not -\begin{example} -\begin{codeblock} -template struct A { - A(T, int*); // \#1 - A(A&, int*); // \#2 - enum { value }; -}; - -template A(T&&, int*) -> A; // \#3 - -A a{1, 0}; // uses \#1 to deduce \tcode{A} and initializes with \#1 -A b{a, 0}; // uses \#3 (not \#2) to deduce \tcode{A\&>} and initializes with \#1 -\end{codeblock} -\end{example} -or, if not that, - \item \tcode{F1} is not a function template specialization and @@ -1679,7 +1673,47 @@ \tcode{F1} is more specialized than the template for \tcode{F2} -according to the partial ordering rules described in~\ref{temp.func.order}. +according to the partial ordering rules described in~\ref{temp.func.order}, +or, if not that, + +\item +\tcode{F1} is generated from a +\grammarterm{deduction-guide}~(\ref{over.match.class.deduct}) +and \tcode{F2} is not, or, if not that, + +\item +\tcode{F1} is the copy deduction candidate~(\ref{over.match.class.deduct}) +and \tcode{F2} is not, or, if not that, + +\item +\tcode{F1} is generated from a non-template constructor +and \tcode{F2} is generated from a constructor template. +\begin{example} +\begin{codeblock} +template struct A { + using value_type = T; + A(value_type); // \#1 + A(const A&); // \#2 + A(T, T, int); // \#3 + template + A(int, T, U); // \#4 + // \#5 is the copy deduction candidate, \tcode{A(A)} +}; + +A x(1, 2, 3); // uses \#3, generated from a non-template constructor + +template +A(T) -> A; // \#6, less specialized than \#5 + +A a(42); // uses \#6 to deduce \tcode{A} and \#1 to initialize +A b = a; // uses \#5 to deduce \tcode{A} and \#2 to initialize + +template +A(A) -> A>; // \#7, as specialized as \#5 + +A b2 = a; // uses \#7 to deduce \tcode{A>} and \#1 to initialize +\end{codeblock} +\end{example} \end{itemize} \pnum @@ -1808,7 +1842,7 @@ \term{standard conversion sequence}~(\ref{over.ics.scs}), \item a -\grammarterm{user-defined conversion sequence}~(\ref{over.ics.user}), or +\term{user-defined conversion sequence}~(\ref{over.ics.user}), or \item an \term{ellipsis conversion sequence}~(\ref{over.ics.ellipsis}). @@ -3303,7 +3337,7 @@ \term{literal suffix identifier}. Some literal suffix identifiers are reserved for future standardization; see~\ref{usrlit.suffix}. A declaration whose \grammarterm{literal-operator-id} uses -such a literal suffix identifier is ill-formed; no diagnostic required. +such a literal suffix identifier is ill-formed, no diagnostic required. \pnum A declaration whose \grammarterm{declarator-id} is a diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 703c5ceac9..fda5256780 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -53,7 +53,7 @@ \>\terminal{\# define}\>\>identifier replacement-list new-line\br \>\terminal{\# define}\>\>identifier lparen identifier-list\opt{} \terminal{)} replacement-list new-line\br \>\terminal{\# define}\>\>identifier lparen \terminal{... )} replacement-list new-line\br -\>\terminal{\# define}\>\>identifier lparen identifier-list, \terminal{... )} replacement-list new-line\br +\>\terminal{\# 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 @@ -188,31 +188,31 @@ \indextext{inclusion!conditional|see{preprocessing directive, conditional inclusion}} \indextext{\idxcode{defined}}% -\begin{ncbnf} +\begin{bnf} \nontermdef{defined-macro-expression}\br \terminal{defined} identifier\br \terminal{defined (} identifier \terminal{)} -\end{ncbnf} +\end{bnf} -\begin{ncbnf} +\begin{bnf} \nontermdef{h-preprocessing-token}\br \textnormal{any \grammarterm{preprocessing-token} other than \terminal{>}} -\end{ncbnf} +\end{bnf} -\begin{ncbnf} +\begin{bnf} \nontermdef{h-pp-tokens}\br h-preprocessing-token\br h-pp-tokens h-preprocessing-token -\end{ncbnf} +\end{bnf} \indextext{__HAS_INCLUDE@\xname{has_include}}% -\begin{ncbnf} +\begin{bnf} \nontermdef{has-include-expression}\br \terminal{\xname{has_include} ( <} h-char-sequence \terminal{> )}\br \terminal{\xname{has_include} ( "} q-char-sequence \terminal{" )}\br \terminal{\xname{has_include} (} string-literal \terminal{)}\br \terminal{\xname{has_include} ( <} h-pp-tokens \terminal{> )} -\end{ncbnf} +\end{bnf} \pnum The expression that controls conditional inclusion @@ -309,7 +309,7 @@ \tcode{true} and \tcode{false}, -are replaced with the pp-number +are replaced with the \grammarterm{pp-number} \tcode{0}, and then each preprocessing token is converted into a token. \begin{note} @@ -572,7 +572,7 @@ #if VERSION == 1 #define INCFILE "vers1.h" #elif VERSION == 2 - #define INCFILE "vers2.h" // and so on + #define INCFILE "vers2.h" // and so on #else #define INCFILE "versN.h" #endif @@ -668,8 +668,7 @@ \end{ncsimplebnf} defines an -\indextext{macro!object-like}% -\defn{object-like macro} that +\defnx{object-like macro}{macro!object-like} that causes each subsequent instance of the macro name\footnote{Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences @@ -690,8 +689,7 @@ \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} -\indextext{macro!function-like}% -defines a \defn{function-like macro} +defines a \defnx{function-like macro}{macro!function-like} with parameters, whose use is similar syntactically to a function call. The parameters @@ -768,7 +766,7 @@ \rSec2[cpp.stringize]{The \tcode{\#} operator}% \indextext{\#\#0 operator@\tcode{\#} operator}% -\indextext{stringize|see{\tcode{\#}}} +\indextext{stringize|see{\tcode{\#} operator}} \pnum Each @@ -815,7 +813,7 @@ \rSec2[cpp.concat]{The \tcode{\#\#} operator}% \indextext{\#\#1 operator@\tcode{\#\#} operator}% -\indextext{concatenation!macro argument|see{\tcode{\#\#}}} +\indextext{concatenation!macro argument|see{\tcode{\#\#} operator}} \pnum A @@ -1022,7 +1020,7 @@ #define LOW LOW ", world" debug(1, 2); -fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away +fputs(str(strncmp("abc@\textbackslash@0d", "abc", '@\textbackslash@4') // this goes away == 0) str(: @\atsign\textbackslash@n), s); #include xstr(INCFILE(2).h) glue(HIGH, LOW); @@ -1034,7 +1032,7 @@ \begin{codeblock} printf("x" "1" "= %d, x" "2" "= %s", x1, x2); fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0" ": @\atsign\textbackslash@n", s); -#include "vers2.h" @\textit{(after macro replacement, before file access)}@ +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ "hello"; "hello" ", world" \end{codeblock} @@ -1044,7 +1042,7 @@ \begin{codeblock} printf("x1= %d, x2= %s", x1, x2); fputs("strncmp(@\textbackslash@"abc@\textbackslash\textbackslash@0d@\textbackslash@", @\textbackslash@"abc@\textbackslash@", '@\textbackslash\textbackslash@4') == 0: @\atsign\textbackslash@n", s); -#include "vers2.h" @\textit{(after macro replacement, before file access)}@ +#include "vers2.h" @\textrm{(\textit{after macro replacement, before file access})}@ "hello"; "hello, world" \end{codeblock} @@ -1091,10 +1089,10 @@ But the following redefinitions are invalid: \begin{codeblock} -#define OBJ_LIKE (0) // different token sequence -#define OBJ_LIKE (1 - 1) // different white space -#define FUNC_LIKE(b) ( a ) // different parameter usage -#define FUNC_LIKE(b) ( b ) // different parameter spelling +#define OBJ_LIKE (0) // different token sequence +#define OBJ_LIKE (1 - 1) // different white space +#define FUNC_LIKE(b) ( a ) // different parameter usage +#define FUNC_LIKE(b) ( b ) // different parameter spelling \end{codeblock} \end{example} @@ -1119,7 +1117,7 @@ fprintf(stderr, "X = %d\n", x); puts("The first, second, and third items."); ((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y)); - + \end{codeblock} \end{example} \indextext{macro!replacement|)} @@ -1282,13 +1280,13 @@ \indextext{__STDCPP_DEFAULT_NEW_ALIGNMENT__@\mname{STDCPP_DEFAULT_NEW_ALIGNMENT}}% \item \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\\ -An integer literal of type \tcode{std\colcol{}size_t} +An integer literal of type \tcode{std::size_t} whose value is the alignment guaranteed by a call to \tcode{operator new(std::size_t)} or \tcode{operator new[](std::size_t)}. \begin{note} Larger alignments will be passed to -\tcode{operator new(std::size_t, std::align_val_t)}, etc. (\ref{expr.new}). +\tcode{operator new(std::size_t, std::align_val_t)}, etc.~(\ref{expr.new}). \end{note} \indextext{__TIME__@\mname{TIME}}% diff --git a/source/regex.tex b/source/regex.tex index 192822e342..44d2c9281a 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -268,23 +268,23 @@ using error_type = @\placeholder{T3}@; } - // \ref{re.badexp}, class regex_error + // \ref{re.badexp}, class \tcode{regex_error} class regex_error; - // \ref{re.traits}, class template regex_traits + // \ref{re.traits}, class template \tcode{regex_traits} template struct regex_traits; - // \ref{re.regex}, class template basic_regex + // \ref{re.regex}, class template \tcode{basic_regex} template > class basic_regex; using regex = basic_regex; using wregex = basic_regex; - // \ref{re.regex.swap}, basic_regex swap + // \ref{re.regex.swap}, \tcode{basic_regex} swap template void swap(basic_regex& e1, basic_regex& e2); - // \ref{re.submatch}, class template sub_match + // \ref{re.submatch}, class template \tcode{sub_match} template class sub_match; @@ -293,7 +293,7 @@ using ssub_match = sub_match; using wssub_match = sub_match; - // \ref{re.submatch.op}, sub_match non-member operators + // \ref{re.submatch.op}, \tcode{sub_match} non-member operators template bool operator==(const sub_match& lhs, const sub_match& rhs); template @@ -437,7 +437,7 @@ basic_ostream& operator<<(basic_ostream& os, const sub_match& m); - // \ref{re.results}, class template match_results + // \ref{re.results}, class template \tcode{match_results} template >> class match_results; @@ -447,7 +447,7 @@ using smatch = match_results; using wsmatch = match_results; - // match_results comparisons + // \tcode{match_results} comparisons template bool operator==(const match_results& m1, const match_results& m2); @@ -455,12 +455,12 @@ bool operator!=(const match_results& m1, const match_results& m2); - // \ref{re.results.swap}, match_results swap + // \ref{re.results.swap}, \tcode{match_results} swap template void swap(match_results& m1, match_results& m2); - // \ref{re.alg.match}, function template regex_match + // \ref{re.alg.match}, function template \tcode{regex_match} template bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results& m, @@ -495,7 +495,7 @@ const basic_regex& e, regex_constants::match_flag_type flags = regex_constants::match_default); - // \ref{re.alg.search}, function template regex_search + // \ref{re.alg.search}, function template \tcode{regex_search} template bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results& m, @@ -532,7 +532,7 @@ regex_constants::match_flag_type = regex_constants::match_default) = delete; - // \ref{re.alg.replace}, function template regex_replace + // \ref{re.alg.replace}, function template \tcode{regex_replace} template OutputIterator @@ -573,7 +573,7 @@ const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default); - // \ref{re.regiter}, class template regex_iterator + // \ref{re.regiter}, class template \tcode{regex_iterator} template ::value_type, class traits = regex_traits> @@ -584,7 +584,7 @@ using sregex_iterator = regex_iterator; using wsregex_iterator = regex_iterator; - // \ref{re.tokiter}, class template regex_token_iterator + // \ref{re.tokiter}, class template \tcode{regex_token_iterator} template ::value_type, class traits = regex_traits> @@ -625,17 +625,17 @@ \begin{codeblock} namespace std::regex_constants { using syntax_option_type = @\textit{T1}@; - constexpr syntax_option_type icase = @\unspec@; - constexpr syntax_option_type nosubs = @\unspec@; - constexpr syntax_option_type optimize = @\unspec@; - constexpr syntax_option_type collate = @\unspec@; - constexpr syntax_option_type ECMAScript = @\unspec@; - constexpr syntax_option_type basic = @\unspec@; - constexpr syntax_option_type extended = @\unspec@; - constexpr syntax_option_type awk = @\unspec@; - constexpr syntax_option_type grep = @\unspec@; - constexpr syntax_option_type egrep = @\unspec@; - constexpr syntax_option_type multiline = @\unspec@; + inline constexpr syntax_option_type icase = @\unspec@; + inline constexpr syntax_option_type nosubs = @\unspec@; + inline constexpr syntax_option_type optimize = @\unspec@; + inline constexpr syntax_option_type collate = @\unspec@; + inline constexpr syntax_option_type ECMAScript = @\unspec@; + inline constexpr syntax_option_type basic = @\unspec@; + inline constexpr syntax_option_type extended = @\unspec@; + inline constexpr syntax_option_type awk = @\unspec@; + inline constexpr syntax_option_type grep = @\unspec@; + inline constexpr syntax_option_type egrep = @\unspec@; + inline constexpr syntax_option_type multiline = @\unspec@; } \end{codeblock} @@ -767,19 +767,19 @@ \begin{codeblock} namespace std::regex_constants { using match_flag_type = @\textit{T2}@; - constexpr match_flag_type match_default = {}; - constexpr match_flag_type match_not_bol = @\unspec@; - constexpr match_flag_type match_not_eol = @\unspec@; - constexpr match_flag_type match_not_bow = @\unspec@; - constexpr match_flag_type match_not_eow = @\unspec@; - constexpr match_flag_type match_any = @\unspec@; - constexpr match_flag_type match_not_null = @\unspec@; - constexpr match_flag_type match_continuous = @\unspec@; - constexpr match_flag_type match_prev_avail = @\unspec@; - constexpr match_flag_type format_default = {}; - constexpr match_flag_type format_sed = @\unspec@; - constexpr match_flag_type format_no_copy = @\unspec@; - constexpr match_flag_type format_first_only = @\unspec@; + inline constexpr match_flag_type match_default = {}; + inline constexpr match_flag_type match_not_bol = @\unspec@; + inline constexpr match_flag_type match_not_eol = @\unspec@; + inline constexpr match_flag_type match_not_bow = @\unspec@; + inline constexpr match_flag_type match_not_eow = @\unspec@; + inline constexpr match_flag_type match_any = @\unspec@; + inline constexpr match_flag_type match_not_null = @\unspec@; + inline constexpr match_flag_type match_continuous = @\unspec@; + inline constexpr match_flag_type match_prev_avail = @\unspec@; + inline constexpr match_flag_type format_default = {}; + inline constexpr match_flag_type format_sed = @\unspec@; + inline constexpr match_flag_type format_no_copy = @\unspec@; + inline constexpr match_flag_type format_first_only = @\unspec@; } \end{codeblock} @@ -847,8 +847,8 @@ \indexlibrary{\idxcode{match_prev_avail}}% \tcode{match_prev_avail} & \verb!--first! is a valid iterator position. When this flag is -set the flags match_not_bol and match_not_bow shall be ignored by the -regular expression algorithms~\ref{re.alg} and iterators~\ref{re.iter}. +set the flags \tcode{match_not_bol} and \tcode{match_not_bow} shall be ignored by the +regular expression algorithms~(\ref{re.alg}) and iterators~(\ref{re.iter}). \\ \rowsep % \indexlibrary{\idxcode{format_default}}% @@ -889,19 +889,19 @@ \begin{codeblock} namespace std::regex_constants { using error_type = @\textit{T3}@; - constexpr error_type error_collate = @\unspec@; - constexpr error_type error_ctype = @\unspec@; - constexpr error_type error_escape = @\unspec@; - constexpr error_type error_backref = @\unspec@; - constexpr error_type error_brack = @\unspec@; - constexpr error_type error_paren = @\unspec@; - constexpr error_type error_brace = @\unspec@; - constexpr error_type error_badbrace = @\unspec@; - constexpr error_type error_range = @\unspec@; - constexpr error_type error_space = @\unspec@; - constexpr error_type error_badrepeat = @\unspec@; - constexpr error_type error_complexity = @\unspec@; - constexpr error_type error_stack = @\unspec@; + inline constexpr error_type error_collate = @\unspec@; + inline constexpr error_type error_ctype = @\unspec@; + inline constexpr error_type error_escape = @\unspec@; + inline constexpr error_type error_backref = @\unspec@; + inline constexpr error_type error_brack = @\unspec@; + inline constexpr error_type error_paren = @\unspec@; + inline constexpr error_type error_brace = @\unspec@; + inline constexpr error_type error_badbrace = @\unspec@; + inline constexpr error_type error_range = @\unspec@; + inline constexpr error_type error_space = @\unspec@; + inline constexpr error_type error_badrepeat = @\unspec@; + inline constexpr error_type error_complexity = @\unspec@; + inline constexpr error_type error_stack = @\unspec@; } \end{codeblock} @@ -1407,6 +1407,11 @@ // \ref{re.regex.swap}, swap void swap(basic_regex&); }; + + template + basic_regex(ForwardIterator, ForwardIterator, + regex_constants::syntax_option_type = regex_constants::ECMAScript) + -> basic_regex::value_type>; } \end{codeblock} @@ -1465,7 +1470,7 @@ designated by \tcode{p}, and interpreted according to the flags \tcode{f}. \pnum\postconditions -\tcode{flags()} returns \tcode{f}. +\tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. \end{itemdescr} @@ -1489,7 +1494,7 @@ interpreted according the flags specified in \tcode{f}. \pnum\postconditions -\tcode{flags()} returns \tcode{f}. +\tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. \end{itemdescr} @@ -1542,7 +1547,7 @@ flags specified in \tcode{f}. \pnum\postconditions -\tcode{flags()} returns \tcode{f}. +\tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. \end{itemdescr} @@ -1566,7 +1571,7 @@ interpreted according to the flags specified in \tcode{f}. \pnum\postconditions -\tcode{flags()} returns \tcode{f}. +\tcode{flags()} returns \tcode{f}. \tcode{mark_count()} returns the number of marked sub-expressions within the expression. \end{itemdescr} @@ -1709,7 +1714,7 @@ \pnum \effects Assigns the regular expression contained in the string \tcode{s}, interpreted according the flags specified in \tcode{f}. -If an exception is thrown, \tcode{*this} is unchanged. +If an exception is thrown, \tcode{*this} is unchanged. \pnum \postconditions @@ -2650,7 +2655,7 @@ \rSec2[re.results.state]{\tcode{match_results} state} -\indexlibrarymember{match_results}{state}% +\indexlibrarymember{match_results}{ready}% \begin{itemdecl} bool ready() const; \end{itemdecl} @@ -2770,7 +2775,7 @@ \pnum \returns A reference to the \tcode{sub_match} object representing the character sequence from the start of the string being -matched/searched to the start of the match found. +matched/searched to the start of the match found. \end{itemdescr} \indexlibrarymember{match_results}{suffix}% @@ -2785,7 +2790,7 @@ \pnum \returns A reference to the \tcode{sub_match} object representing the character sequence from the end of the match found to the end of the -string being matched/searched. +string being matched/searched. \end{itemdescr} \indexlibrarymember{match_results}{begin}% @@ -2797,7 +2802,7 @@ \begin{itemdescr} \pnum\returns A starting iterator that enumerates over all the sub-expressions stored in \tcode{*this}. -\end{itemdescr} +\end{itemdescr} \indexlibrarymember{match_results}{end}% \begin{itemdecl} @@ -2807,7 +2812,7 @@ \begin{itemdescr} \pnum\returns A terminating iterator that enumerates over all the -sub-expressions stored in \tcode{*this}. +sub-expressions stored in \tcode{*this}. \end{itemdescr} \rSec2[re.results.form]{\tcode{match_results} formatting} @@ -3499,7 +3504,7 @@ end-of-sequence iterators are always equal. An end-of-sequence iterator is not equal to a non-end-of-sequence iterator. Two non-end-of-sequence iterators are equal when they are constructed from -the same arguments. +the same arguments. \begin{codeblock} namespace std { @@ -4158,8 +4163,8 @@ The behavior of the internal finite state machine representation when used to match a sequence of characters is as described in ECMA-262. The behavior is modified according -to any match_flag_type flags~\ref{re.matchflag} specified when using the regular expression -object in one of the regular expression algorithms~\ref{re.alg}. The behavior is also +to any match_flag_type flags~(\ref{re.matchflag}) specified when using the regular expression +object in one of the regular expression algorithms~(\ref{re.alg}). The behavior is also localized by interaction with the traits class template parameter as follows: \begin{itemize} \item During matching of a regular expression finite state machine diff --git a/source/special.tex b/source/special.tex index fde134161f..757f0ec576 100644 --- a/source/special.tex +++ b/source/special.tex @@ -3,8 +3,6 @@ \gramSec[gram.special]{Special member functions} -\indextext{special member function|see{constructor, destructor, inline function, -user-defined conversion, virtual function}}% \indextext{\idxcode{X(X\&)}|see{constructor, copy}}% \indextext{~@\tcode{\tilde}|see{destructor}}% \indextext{assignment!copy|see{assignment operator, copy}}% @@ -70,7 +68,8 @@ classes are called its \term{potentially constructed subobjects}. \rSec1[class.ctor]{Constructors}% -\indextext{constructor} +\indextext{constructor}% +\indextext{special member function|see{constructor}}% \pnum Constructors do not have names. @@ -181,7 +180,7 @@ \item \tcode{X} is a union that has a variant member with a non-trivial default constructor and no variant member of \tcode{X} has a default member initializer, - + \item \tcode{X} is a non-union class that has a variant member \tcode{M} with a non-trivial default constructor and no variant member of the anonymous union containing \tcode{M} @@ -214,7 +213,7 @@ \pnum A default constructor is -trivial +\defnx{trivial}{constructor!default!trivial} if it is not user-provided and if: \begin{itemize} @@ -234,7 +233,7 @@ \end{itemize} Otherwise, the default constructor is -\grammarterm{non-trivial}. +\defnx{non-trivial}{constructor!default!non-trivial}. \pnum \indextext{constructor!implicitly defined}% @@ -518,7 +517,7 @@ The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer~(\ref{dcl.init}). The second context is when a copy constructor is called to copy an element of -an array while the entire array is copied~(\ref{expr.prim.lambda},~\ref{class.copy}). +an array while the entire array is copied~(\ref{expr.prim.lambda.capture},~\ref{class.copy}). In either case, if the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any. @@ -561,7 +560,7 @@ that is, if \tcode{obj1} is an object with the same storage duration as the temporary and -created before the temporary is created +created before the temporary is created the temporary shall be destroyed before \tcode{obj1} is destroyed; @@ -903,7 +902,7 @@ \end{codeblock} The \tcode{*} is the pointer declarator and not the multiplication operator. \end{example} -This rule also prevents ambiguities for attributes. +This rule also prevents ambiguities for attributes. \begin{example} \begin{codeblock} operator int [[noreturn]] (); // error: \tcode{noreturn} attribute applied to a type @@ -934,7 +933,8 @@ \end{example} \rSec1[class.dtor]{Destructors}% -\indextext{destructor} +\indextext{destructor}% +\indextext{special member function|see{destructor}}% \pnum In a declaration of a destructor, the \grammarterm{declarator} is a @@ -1006,7 +1006,6 @@ \pnum \indextext{generated destructor|see{destructor, default}}% \indextext{destructor!default}% -\indextext{destructor!non-trivial}% If a class has no user-declared destructor, a destructor is implicitly declared as defaulted~(\ref{dcl.fct.def}). @@ -1045,7 +1044,7 @@ \end{itemize} Otherwise, the destructor is -\grammarterm{non-trivial}. +\defnx{non-trivial}{destructor!non-trivial}. \pnum \indextext{destructor!implicitly defined}% @@ -1146,7 +1145,7 @@ \pnum At the point of definition of a virtual destructor (including an implicit -definition~(\ref{class.copy})), the non-array deallocation function is +definition~(\ref{class.copy})), the non-array deallocation function is determined as if for the expression \tcode{delete this} appearing in a non-virtual destructor of the destructor's class (see~\ref{expr.delete}). If the lookup fails or if the deallocation function has @@ -1197,7 +1196,7 @@ \end{example} \begin{note} An explicit destructor call must always be written using -a member access operator~(\ref{expr.ref}) or a qualified-id~(\ref{expr.prim}); +a member access operator~(\ref{expr.ref}) or a \grammarterm{qualified-id}~(\ref{expr.prim}); in particular, the \grammarterm{unary-expression} \tcode{\~{}X()} @@ -1690,7 +1689,7 @@ The target constructor is selected by overload resolution. Once the target constructor returns, the body of the delegating constructor is executed. If a constructor delegates to itself directly or indirectly, -the program is ill-formed; no diagnostic is required. \begin{example} +the program is ill-formed, no diagnostic required. \begin{example} \begin{codeblock} struct C { @@ -1826,7 +1825,7 @@ \pnum If a given non-static data member has both a default member initializer and a \grammarterm{mem-initializer}, the initialization specified by the -\grammarterm{mem-initializer} is performed, and the non-static data member's +\grammarterm{mem-initializer} is performed, and the non-static data member's default member initializer is ignored. \begin{example} Given % The comment below is misrendered with an overly large space before 'effects' @@ -1843,7 +1842,7 @@ the \tcode{A(int)} constructor will simply initialize \tcode{i} to the value of \tcode{arg}, and the \indextext{side effects}% -side effects in \tcode{i}'s default member initializer +side effects in \tcode{i}'s default member initializer will not take place. \end{example} @@ -1887,13 +1886,13 @@ as they appear in the \grammarterm{base-specifier-list} (regardless of the order of the -\grammarterm{mem-initializers}). +\grammarterm{mem-initializer}{s}). \item \indextext{initialization!order of member}% Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the -\grammarterm{mem-initializers}). +\grammarterm{mem-initializer}{s}). \item Finally, the \grammarterm{compound-statement} of the constructor body is executed. @@ -2395,10 +2394,6 @@ \indextext{construction|)}% \rSec1[class.copy]{Copying and moving class objects}% -\indextext{copy!class object|see{constructor, copy; assignment, copy}}% -\indextext{move!class object|see{constructor, move; assignment, move}}% -\indextext{operator!copy assignment|see{assignment, copy}}% -\indextext{operator!move assignment|see{assignment, move}} \pnum A class object can be copied or moved in two ways: @@ -2427,6 +2422,8 @@ \pnum \indextext{constructor!copy|(}% \indextext{constructor!move|(}% +\indextext{copy!class object|see{constructor, copy}}% +\indextext{move!class object|see{constructor, move}}% A non-template constructor for class \tcode{X} is @@ -2461,7 +2458,7 @@ A non-template constructor for class \tcode{X} is a move constructor if its first parameter is of type \tcode{X\&\&}, \tcode{const X\&\&}, \tcode{volatile X\&\&}, or \tcode{const volatile X\&\&}, and either there are -no other parameters or else all other parameters have default +no other parameters or else all other parameters have default arguments~(\ref{dcl.fct.default}). \begin{example} \tcode{Y::Y(Y\&\&)} is a move constructor. \begin{codeblock} @@ -2629,8 +2626,8 @@ \item a potentially constructed subobject type \tcode{M} (or array thereof) that cannot be copied/moved because overload resolution (\ref{over.match}), as applied to find - \tcode{M}'s - corresponding constructor, results in an ambiguity or + \tcode{M}'s + corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor, @@ -2674,8 +2671,9 @@ the constructor selected to copy/move that member is trivial; \end{itemize} +\indextext{constructor!move!non-trivial}% otherwise the copy/move constructor is -\grammarterm{non-trivial}. +\defnx{non-trivial}{constructor!copy!nontrivial}. \pnum \indextext{constructor!copy!implicitly defined}% @@ -2746,6 +2744,11 @@ \pnum \indextext{assignment operator!copy|(}% \indextext{assignment operator!move|(}% +\indextext{special member function|see{assignment operator}}% +\indextext{copy!class object|see{assignment operator, copy}}% +\indextext{move!class object|see{assignment operator, move}}% +\indextext{operator!copy assignment|see{assignment operator, copy}}% +\indextext{operator!move assignment|see{assignment operator, move}} A user-declared \term{copy} assignment operator \tcode{X::operator=} is a non-static non-template member function of class \tcode{X} with exactly one parameter of type \tcode{X}, \tcode{X\&}, \tcode{const} \tcode{X\&}, @@ -2986,8 +2989,9 @@ the assignment operator selected to copy/move that member is trivial; \end{itemize} +\indextext{assignment operator!move!non-trivial}% otherwise the copy/move assignment operator is -\grammarterm{non-trivial}. +\defnx{non-trivial}{assignment operator!copy!non-trivial}. \pnum \indextext{assignment operator!copy!implicitly defined}% @@ -3102,8 +3106,8 @@ and one copy/move constructor is not executed, there is still one object destroyed for each one constructed.} This elision of copy/move operations, called -\indexdefn{copy elision|see{constructor, copy, elision; constructor, move, elision}}% -\indexdefn{elision!copy|see{constructor, copy, elision; constructor, move, elision}}% +\indexdefn{copy elision|see{constructor, copy, elision}}% +\indexdefn{elision!copy|see{constructor, copy, elision}}% \indexdefn{constructor!copy!elision}\indexdefn{constructor!move!elision}\term{copy elision}, is permitted in the following circumstances (which may be combined to diff --git a/source/statements.tex b/source/statements.tex index 6adfb50902..fb7ba2ed20 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -340,7 +340,7 @@ an integral or enumeration type. If the (possibly converted) type is subject to integral promotions~(\ref{conv.prom}), the condition is converted -to the promoted type. +to the promoted type. Any statement within the \tcode{switch} statement can be labeled with one or more case labels as follows: @@ -392,7 +392,7 @@ required. \indextext{statement!declaration in \tcode{switch}}% Declarations can appear in the substatement of a -\grammarterm{switch-statement}. +\tcode{switch} statement. \end{note} \pnum @@ -478,6 +478,21 @@ Thus after the \tcode{while} statement, \tcode{i} is no longer in scope. \end{example} +\pnum +If a name introduced in an +\grammarterm{init-statement} or \grammarterm{for-range-declaration} +is redeclared in the outermost block of the substatement, the program is ill-formed. +\begin{example} +\begin{codeblock} +void f() { + for (int i = 0; i < 10; ++i) + int i = 0; // error: redeclaration + for (int i : { 1, 2, 3 }) + int i = 1; // error: redeclaration +} +\end{codeblock} +\end{example} + \rSec2[stmt.while]{The \tcode{while} statement}% \indextext{statement!\idxcode{while}} @@ -609,7 +624,7 @@ \end{example} \rSec2[stmt.ranged]{The range-based \tcode{for} statement}% -\indextext{statement!range based \idxcode{for}} +\indextext{statement!range based for@range based \tcode{for}} \pnum The range-based \tcode{for} statement @@ -635,33 +650,33 @@ where \begin{itemize} -\item +\item if the \grammarterm{for-range-initializer} is an \grammarterm{expression}, it is regarded as if it were surrounded by parentheses (so that a comma operator -cannot be reinterpreted as delimiting two \grammarterm{init-declarators}); +cannot be reinterpreted as delimiting two \grammarterm{init-declarator}{s}); \item \tcode{__range}, \tcode{__begin}, and \tcode{__end} are variables defined for exposition only; and \item -\textit{begin-expr} and \textit{end-expr} are determined as follows: +\placeholder{begin-expr} and \placeholder{end-expr} are determined as follows: \begin{itemize} \item if the \grammarterm{for-range-initializer} is an expression of -array type \tcode{R}, \textit{begin-expr} and \textit{end-expr} are +array type \tcode{R}, \placeholder{begin-expr} and \placeholder{end-expr} are \tcode{__range} and \tcode{__range + __bound}, respectively, where \tcode{__bound} is -the array bound. If \tcode{R} is an array of unknown size or an array of +the array bound. If \tcode{R} is an array of unknown bound or an array of incomplete type, the program is ill-formed; \item if the \grammarterm{for-range-initializer} is an expression of class type \tcode{C}, the \grammarterm{unqualified-id}{s} \tcode{begin} and \tcode{end} are looked up in the scope of \tcode{C} as if by class member access lookup~(\ref{basic.lookup.classref}), and if either -(or both) finds at least one declaration, \grammarterm{begin-expr} and -\grammarterm{end-expr} are \tcode{__range.begin()} and \tcode{__range.end()}, +(or both) finds at least one declaration, \placeholder{begin-expr} and +\placeholder{end-expr} are \tcode{__range.begin()} and \tcode{__range.end()}, respectively; -\item otherwise, \textit{begin-expr} and \textit{end-expr} are \tcode{begin(__range)} +\item otherwise, \placeholder{begin-expr} and \placeholder{end-expr} are \tcode{begin(__range)} and \tcode{end(__range)}, respectively, where \tcode{begin} and \tcode{end} are looked up in the associated namespaces~(\ref{basic.lookup.argdep}). \begin{note} Ordinary unqualified lookup~(\ref{basic.lookup.unqual}) is not @@ -892,7 +907,7 @@ \begin{codeblock} void f() { - // ... + // ... goto lx; // ill-formed: jump into scope of \tcode{a} // ... ly: diff --git a/source/std.tex b/source/std.tex index c6583eda32..e77b5a1f82 100644 --- a/source/std.tex +++ b/source/std.tex @@ -25,7 +25,7 @@ \usepackage{color} % define colors for strikeouts and underlines \usepackage{amsmath} % additional math symbols \usepackage{mathrsfs} % mathscr font -\usepackage{microtype} +\usepackage[final]{microtype} \usepackage{multicol} \usepackage{xspace} \usepackage{lmodern} @@ -64,6 +64,7 @@ \makeindex[grammarindex] \makeindex[impldefindex] \makeglossary[xrefindex] +\makeglossary[xrefdelta] %%-------------------------------------------------- %% fix interaction between hyperref and other diff --git a/source/strings.tex b/source/strings.tex index 3eec571561..063bfc211e 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -384,8 +384,7 @@ The two-argument member \tcode{assign} shall be defined identically to the built-in operator \tcode{=}. The two-argument members \tcode{eq} and \tcode{lt} shall be defined identically to the built-in operators -\tcode{==} and \tcode{<} for type \tcode{unsigned} -\tcode{char}. +\tcode{==} and \tcode{<} for type \tcode{unsigned char}. \pnum The member @@ -605,7 +604,7 @@ template<> struct char_traits; template<> struct char_traits; - // \ref{basic.string}, basic_string + // \ref{basic.string}, \tcode{basic_string} template, class Allocator = allocator> class basic_string; @@ -809,11 +808,11 @@ inline namespace literals { inline namespace string_literals { - // \ref{basic.string.literals}, suffix for basic_string literals - string operator "" s(const char* str, size_t len); - u16string operator "" s(const char16_t* str, size_t len); - u32string operator "" s(const char32_t* str, size_t len); - wstring operator "" s(const wchar_t* str, size_t len); + // \ref{basic.string.literals}, suffix for \tcode{basic_string} literals + string operator""s(const char* str, size_t len); + u16string operator""s(const char16_t* str, size_t len); + u32string operator""s(const char32_t* str, size_t len); + wstring operator""s(const wchar_t* str, size_t len); } } } @@ -878,8 +877,8 @@ class basic_string { public: // types: - using traits_type = traits; - using value_type = typename traits::char_type; + using traits_type = traits; + using value_type = charT; using allocator_type = Allocator; using size_type = typename allocator_traits::size_type; using difference_type = typename allocator_traits::difference_type; @@ -919,7 +918,7 @@ basic_string(const basic_string&, const Allocator&); basic_string(basic_string&&, const Allocator&); - ~basic_string(); + ~basic_string(); basic_string& operator=(const basic_string& str); basic_string& operator=(basic_string&& str) noexcept(allocator_traits::propagate_on_container_move_assignment::value || @@ -1135,6 +1134,13 @@ int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; }; + + template::value_type>> + basic_string(InputIterator, InputIterator, Allocator = Allocator()) + -> basic_string::value_type, + char_traits::value_type>, + Allocator>; } \end{codeblock} @@ -1157,10 +1163,10 @@ \tcode{Allocator} to allocate and free storage for the contained \tcode{charT} objects as needed. The \tcode{Allocator} object used shall be obtained as described in \ref{container.requirements.general}. -\begin{note} In every specialization -\tcode{basic_string}, the type -\tcode{traits::char_type} shall be the same type as -\tcode{charT}; see \ref{char.traits}. \end{note} +In every specialization \tcode{basic_string}, +the type \tcode{traits} shall satisfy +the character traits requirements~(\ref{char.traits}), and +the type \tcode{traits::char_type} shall name the same type as \tcode{charT}. \pnum References, pointers, and iterators referring to the elements of a @@ -1473,6 +1479,21 @@ \throws The second form throws nothing if \tcode{alloc == str.get_allocator()}. \end{itemdescr} +\begin{itemdecl} +template::value_type>> + basic_string(InputIterator, InputIterator, Allocator = Allocator()) + -> basic_string::value_type, + char_traits::value_type>, + Allocator>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks Shall not participate in overload resolution if +\tcode{InputIterator} is a type that does not qualify as an input iterator, +or if \tcode{Allocator} is a type that does not qualify as an allocator~(\ref{container.requirements.general}). +\end{itemdescr} \indexlibrarymember{operator=}{basic_string}% \begin{itemdecl} @@ -1803,7 +1824,7 @@ \pnum \remarks Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence. +referring to the elements in the sequence as well as the past-the-end iterator. If no reallocation happens, they remain valid. \end{itemdescr} @@ -2136,7 +2157,7 @@ \requires \range{first}{last} is a valid range. \pnum -\effects Equivalent to \tcode{append(basic_string(first, last))}. +\effects Equivalent to \tcode{append(basic_string(first, last, get_allocator()))}. \pnum \returns @@ -2345,7 +2366,7 @@ \begin{itemdescr} \pnum -\effects Equivalent to \tcode{assign(basic_string(first, last))}. +\effects Equivalent to \tcode{assign(basic_string(first, last, get_allocator()))}. \pnum \returns @@ -2554,7 +2575,7 @@ \pnum \effects Equivalent to -\tcode{insert(p - begin(), basic_string(first, last))}. +\tcode{insert(p - begin(), basic_string(first, last, get_allocator()))}. \pnum \returns An iterator which refers to the copy of the first inserted character, or @@ -2940,7 +2961,7 @@ \requires \range{begin()}{i1}, \range{i1}{i2} and \range{j1}{j2} are valid ranges. \pnum -\effects Calls \tcode{replace(i1 - begin(), i2 - i1, basic_string(j1, j2))}. +\effects Calls \tcode{replace(i1 - begin(), i2 - i1, basic_string(j1, j2, get_allocator()))}. \pnum \returns @@ -2990,7 +3011,7 @@ \pnum \effects Equivalent to: \tcode{traits::copy(s, data() + pos, rlen)}. -\begin{note} This does not terminate \tcode{s} with a null object. \end{note} +\begin{note} This does not terminate \tcode{s} with a null object. \end{note} \pnum \returns @@ -4251,7 +4272,7 @@ If the function extracts no characters, it calls \tcode{is.setstate(ios::failbit)}, which may throw -\tcode{ios_base\colcol{}fail\-ure}~(\ref{iostate.flags}). +\tcode{ios_base::fail\-ure}~(\ref{iostate.flags}). \pnum \returns @@ -4307,7 +4328,7 @@ (in which case, the \tcode{getline} function calls -\tcode{is.setstate(\brk{}ios_base\colcol{}eofbit)}). +\tcode{is.setstate(\brk{}ios_base::eofbit)}). \item \tcode{traits::eq(c, delim)} for the next available input character @@ -4320,7 +4341,7 @@ characters are stored (in which case, the function calls -\tcode{is.setstate(ios_base\colcol{}fail\-bit))}~(\ref{iostate.flags}) +\tcode{is.setstate(ios_base::fail\-bit))}~(\ref{iostate.flags}) \end{itemize} \pnum @@ -4332,9 +4353,9 @@ \pnum If the function extracts no characters, it calls -\tcode{is.setstate(ios_base\colcol{}fail\-bit)} +\tcode{is.setstate(ios_base::fail\-bit)} which may throw -\tcode{ios_base\colcol{}fail\-ure}~(\ref{iostate.flags}). +\tcode{ios_base::fail\-ure}~(\ref{iostate.flags}). \pnum \returns @@ -4573,9 +4594,9 @@ \rSec2[basic.string.literals]{Suffix for \tcode{basic_string} literals} -\indexlibrarymember{operator """" s}{string}% +\indexlibrarymember{operator""""s}{string}% \begin{itemdecl} -string operator "" s(const char* str, size_t len); +string operator""s(const char* str, size_t len); \end{itemdecl} \begin{itemdescr} @@ -4584,9 +4605,9 @@ \tcode{string\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" s}{u16string}% +\indexlibrarymember{operator""""s}{u16string}% \begin{itemdecl} -u16string operator "" s(const char16_t* str, size_t len); +u16string operator""s(const char16_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum @@ -4594,9 +4615,9 @@ \tcode{u16string\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" s}{u32string}% +\indexlibrarymember{operator""""s}{u32string}% \begin{itemdecl} -u32string operator "" s(const char32_t* str, size_t len); +u32string operator""s(const char32_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum @@ -4604,9 +4625,9 @@ \tcode{u32string\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" s}{wstring}% +\indexlibrarymember{operator""""s}{wstring}% \begin{itemdecl} -wstring operator "" s(const wchar_t* str, size_t len); +wstring operator""s(const wchar_t* str, size_t len); \end{itemdecl} \begin{itemdescr} \pnum @@ -4686,10 +4707,10 @@ inline namespace literals { inline namespace string_view_literals { // \ref{string.view.literals}, suffix for \tcode{basic_string_view} literals - constexpr string_view operator "" sv(const char* str, size_t len) noexcept; - constexpr u16string_view operator "" sv(const char16_t* str, size_t len) noexcept; - constexpr u32string_view operator "" sv(const char32_t* str, size_t len) noexcept; - constexpr wstring_view operator "" sv(const wchar_t* str, size_t len) noexcept; + constexpr string_view operator""sv(const char* str, size_t len) noexcept; + constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; + constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept; + constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept; } } } @@ -4875,10 +4896,10 @@ \begin{itemdescr} \pnum -A constant random-access iterator type such that, -for a \tcode{const_iterator it}, -if \tcode{\&*(it + N)} is valid, -then \tcode{\&*(it + N) == (\&*it) + N}. +A type that meets the requirements +of a constant random access iterator~(\ref{random.access.iterators}) and +of a contiguous iterator~(\ref{iterator.requirements.general}) +whose \tcode{value_type} is the template parameter \tcode{charT}. \pnum For a \tcode{basic_string_view str}, any operation that invalidates a pointer in the range \range{str.data()}{str.data() + str.size()} invalidates pointers, iterators, and references returned from \tcode{str}'s methods. @@ -5634,9 +5655,9 @@ \rSec2[string.view.literals]{Suffix for \tcode{basic_string_view} literals} -\indexlibrarymember{operator """" sv}{string_view}% +\indexlibrarymember{operator""""sv}{string_view}% \begin{itemdecl} -constexpr string_view operator "" sv(const char* str, size_t len) noexcept; +constexpr string_view operator""sv(const char* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5645,9 +5666,9 @@ \tcode{string_view\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" sv}{u16string_view}% +\indexlibrarymember{operator""""sv}{u16string_view}% \begin{itemdecl} -constexpr u16string_view operator "" sv(const char16_t* str, size_t len) noexcept; +constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -5655,9 +5676,9 @@ \tcode{u16string_view\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" sv}{u32string_view}% +\indexlibrarymember{operator""""sv}{u32string_view}% \begin{itemdecl} -constexpr u32string_view operator "" sv(const char32_t* str, size_t len) noexcept; +constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -5665,9 +5686,9 @@ \tcode{u32string_view\{str, len\}}. \end{itemdescr} -\indexlibrarymember{operator """" sv}{wstring_view}% +\indexlibrarymember{operator""""sv}{wstring_view}% \begin{itemdecl} -constexpr wstring_view operator "" sv(const wchar_t* str, size_t len) noexcept; +constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -5859,6 +5880,11 @@ The functions \tcode{strerror} and \tcode{strtok} are not required to avoid data races~(\ref{res.on.data.races}). +\pnum +\indextext{signal-safe!\idxcode{memcpy}}% +\indextext{signal-safe!\idxcode{memmove}}% +The functions \tcode{memcpy} and \tcode{memmove} are signal-safe~(\ref{csignal.syn}). + \pnum \begin{note} The functions diff --git a/source/support.tex b/source/support.tex index 76d2a9df4e..23671c4442 100644 --- a/source/support.tex +++ b/source/support.tex @@ -32,12 +32,10 @@ \ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep -\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep +\ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ & & \tcode{} \\ - & & \tcode{} \\ & & \tcode{} \\ - & & \tcode{} \\ & & \tcode{} \\ \end{libsumtab} @@ -51,12 +49,34 @@ \indexlibrary{\idxcode{size_t}}% \indexlibrary{\idxcode{max_align_t}}% \indexlibrary{\idxcode{nullptr_t}}% +\indexlibrary{\idxcode{byte}}% \begin{codeblock} namespace std { using ptrdiff_t = @\seebelow@; using size_t = @\seebelow@; using max_align_t = @\seebelow@; using nullptr_t = decltype(nullptr); + + enum class byte : unsigned char {}; + + // \ref{support.types.byteops}, \tcode{byte} type operations + template + constexpr byte& operator<<=(byte& b, IntType shift) noexcept; + template + constexpr byte operator<<(byte b, IntType shift) noexcept; + template + constexpr byte& operator>>=(byte& b, IntType shift) noexcept; + 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; + constexpr byte& operator&=(byte& l, byte r) noexcept; + constexpr byte operator&(byte l, byte r) noexcept; + constexpr byte& operator^=(byte& l, byte r) noexcept; + constexpr byte operator^(byte l, byte r) noexcept; + constexpr byte operator~(byte b) noexcept; + template + constexpr IntType to_integer(byte b) noexcept; } #define NULL @\seebelow@ @@ -67,7 +87,9 @@ The contents and meaning of the header \tcode{} are the same as the C standard library header \tcode{}, except that it does not declare the type \tcode{wchar_t}, -and except as noted in +that it also declares the type \tcode{byte} +and its associated operations~(\ref{support.types.byteops}), +and as noted in \ref{support.types.nullptr} and \ref{support.types.layout}. @@ -143,8 +165,8 @@ // Exposition-only function type aliases extern "C" using @\placeholdernc{c-atexit-handler}@ = void(); // \expos extern "C++" using @\placeholdernc{atexit-handler}@ = void(); // \expos - extern "C" using @\placeholdernc{c-compare-pred}@ = int(const void* , const void*); // \expos - extern "C++" using @\placeholdernc{compare-pred}@ = int(const void* , const void*); // \expos + extern "C" using @\placeholdernc{c-compare-pred}@ = int(const void*, const void*); // \expos + extern "C++" using @\placeholdernc{compare-pred}@ = int(const void*, const void*); // \expos // \ref{support.start.term}, start and termination [[noreturn]] void abort() noexcept; @@ -314,6 +336,158 @@ \xref Alignment~(\ref{basic.align}), Sizeof~(\ref{expr.sizeof}), Additive operators~(\ref{expr.add}), Free store~(\ref{class.free}), and ISO C~7.19. +\rSec2[support.types.byteops]{\tcode{byte} type operations} + +\indexlibrarymember{operator<<=}{byte}% +\begin{itemdecl} +template + constexpr byte& operator<<=(byte& b, IntType shift) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \remarks This function shall not participate in overload resolution unless +\tcode{is_integral_v} is \tcode{true}. + +\pnum \effects Equivalent to: +\tcode{return b = byte(static_cast(b) << shift);} +\end{itemdescr} + +\indexlibrarymember{operator<<}{byte}% +\begin{itemdecl} +template + constexpr byte operator<<(byte b, IntType shift) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \remarks This function shall not participate in overload resolution unless +\tcode{is_integral_v} is \tcode{true}. + +\pnum \effects Equivalent to: +\tcode{return byte(static_cast(b) << shift);} +\end{itemdescr} + +\indexlibrarymember{operator>>=}{byte}% +\begin{itemdecl} +template + constexpr byte& operator>>=(byte& b, IntType shift) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \remarks This function shall not participate in overload resolution unless +\tcode{is_integral_v} is \tcode{true}. + +\pnum \effects Equivalent to: +\tcode{return b = byte(static_cast(b) >> shift);} +\end{itemdescr} + +\indexlibrarymember{operator>>}{byte}% +\begin{itemdecl} +template + constexpr byte operator>>(byte b, IntType shift) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \remarks This function shall not participate in overload resolution unless +\tcode{is_integral_v} is \tcode{true}. + +\pnum \effects Equivalent to: +\tcode{return byte(static_cast(b) >> shift);} +\end{itemdescr} + +\indexlibrarymember{operator"|=}{byte}% +\begin{itemdecl} +constexpr byte& operator|=(byte& l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return l = byte(static_cast(l) | static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator"|}{byte}% +\begin{itemdecl} +constexpr byte operator|(byte l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return byte(static_cast(l) | static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\&=}{byte}% +\begin{itemdecl} +constexpr byte& operator&=(byte& l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return l = byte(static_cast(l) & static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\&}{byte}% +\begin{itemdecl} +constexpr byte operator&(byte l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return byte(static_cast(l) & static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\caret=}{byte}% +\begin{itemdecl} +constexpr byte& operator^=(byte& l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return l = byte(static_cast(l) ^ static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\caret}{byte}% +\begin{itemdecl} +constexpr byte operator^(byte l, byte r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: +\begin{codeblock} +return byte(static_cast(l) ^ static_cast(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator\~{}}{byte}% +\begin{itemdecl} +constexpr byte operator~(byte b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum \effects Equivalent to: \tcode{return byte(\~static_cast(b));} +\end{itemdescr} + +\indexlibrarymember{to_integer}{byte}% +\begin{itemdecl} +template + constexpr IntType to_integer(byte b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\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);} +\end{itemdescr} + \rSec1[support.limits]{Implementation properties} \rSec2[support.limits.general]{General} @@ -340,7 +514,7 @@ enum float_round_style; enum float_denorm_style; - // \ref{numeric.limits}, class template numeric_limits + // \ref{numeric.limits}, class template \tcode{numeric_limits} template class numeric_limits; template<> class numeric_limits; @@ -547,6 +721,10 @@ \rSec3[numeric.limits.members]{\tcode{numeric_limits} members} +\pnum +\indextext{signal-safe!\idxcode{numeric_limits} members}% +Each member function defined in this subclause is signal-safe~(\ref{csignal.syn}). + \indexlibrarymember{min}{numeric_limits}% \begin{itemdecl} static constexpr T min() noexcept; @@ -730,9 +908,9 @@ \begin{itemdescr} \pnum Measure of the maximum rounding error.\footnote{Rounding error is described in -ISO/IEC 10967-1 Language independent arithmetic - Part 1 -Section 5.2.8 and -Annex A Rationale Section A.5.2.8 - Rounding constants.} +LIA-1 +Section 5.2.4 and +Annex C Rationale Section C.5.2.4 --- Rounding and rounding constants.} \end{itemdescr} \indexlibrarymember{min_exponent}{numeric_limits}% @@ -1442,6 +1620,8 @@ The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to \tcode{atexit()}~(\ref{basic.start.term}). +\indextext{signal-safe!\idxcode{_Exit}}% +The function \tcode{_Exit} is signal-safe~(\ref{csignal.syn}). \end{itemdescr} \indexlibrary{\idxcode{abort}}% @@ -1460,8 +1640,8 @@ automatic, thread, or static storage duration and without calling functions passed to \tcode{atexit()}~(\ref{basic.start.term}). -% -\indexlibrary{\idxcode{atexit}}% +\indextext{signal-safe!\idxcode{abort}}% +The function \tcode{abort} is signal-safe~(\ref{csignal.syn}). \end{itemdescr} \indexlibrary{\idxcode{atexit}}% @@ -1601,7 +1781,9 @@ function does not provide a handler for a thrown exception, \tcode{std::terminate()} shall be called.\indexlibrary{\idxcode{terminate}} \begin{note} -\tcode{at_quick_exit} may call a registered function from a different thread +A function registered via \tcode{at_quick_exit} +is invoked by the thread that calls \tcode{quick_exit}, +which can be a different thread than the one that registered it, so registered functions should not rely on the identity of objects with thread storage duration. \end{note} @@ -1610,6 +1792,11 @@ The standard file buffers are not flushed. \end{note} +\pnum +\remarks +\indextext{signal-safe!\idxcode{quick_exit}}% +The function \tcode{quick_exit} is signal-safe~(\ref{csignal.syn}) +when the functions registered with \tcode{at_quick_exit} are. \end{itemdescr} \xref~\ref{basic.start}, \ref{basic.start.term}, @@ -1645,8 +1832,8 @@ template constexpr T* launder(T* p) noexcept; // \ref{hardware.interference}, hardware interference size - static constexpr size_t hardware_destructive_interference_size = @\impdef{}@; - static constexpr size_t hardware_constructive_interference_size = @\impdef{}@; + 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); @@ -1731,7 +1918,7 @@ \replaceabledesc{either} \pnum -\required +\required Return a non-null pointer to suitably aligned storage~(\ref{basic.stc.dynamic}), or else throw a \tcode{bad_alloc} @@ -1854,9 +2041,9 @@ its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) -\tcode{operator new(std\colcol{}size_t)} +\tcode{operator new(std::size_t)} or -\tcode{operator new(std\colcol{}size_t, std\colcol{}align_val_t)} +\tcode{operator new(std::size_t, std::align_val_t)} which has not been invalidated by an intervening call to \tcode{operator delete}. @@ -2108,9 +2295,9 @@ its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) -\tcode{operator new[](std\colcol{}size_t)} +\tcode{operator new[](std::size_t)} or -\tcode{operator new[](std\colcol{}size_t, std\colcol{}align_val_t)} +\tcode{operator new[](std::size_t, std::align_val_t)} which has not been invalidated by an intervening call to \tcode{operator delete[]}. @@ -2555,10 +2742,9 @@ struct X { const int n; }; X *p = new X{3}; const int a = p->n; -new (p) X{5}; // \tcode{p} does not point to new object (\ref{basic.life}) - // because \tcode{X::n} is \tcode{const} -const int b = p->n; // undefined behavior -const int c = std::launder(p)->n; // OK +new (p) X{5}; // \tcode{p} does not point to new object (\ref{basic.life}) because \tcode{X::n} is \tcode{const} +const int b = p->n; // undefined behavior +const int c = std::launder(p)->n; // OK \end{codeblock} \end{example} \end{itemdescr} @@ -2567,7 +2753,7 @@ \indexlibrary{\idxcode{hardware_destructive_interference_size}}% \begin{itemdecl} -constexpr size_t hardware_destructive_interference_size = @\impdef{}@; +inline constexpr size_t hardware_destructive_interference_size = @\impdef{}@; \end{itemdecl} \pnum @@ -2589,7 +2775,7 @@ \indexlibrary{\idxcode{hardware_constructive_interference_size}}% \begin{itemdecl} -constexpr size_t hardware_constructive_interference_size = @\impdef{}@; +inline constexpr size_t hardware_constructive_interference_size = @\impdef{}@; \end{itemdecl} \pnum @@ -2653,8 +2839,8 @@ size_t hash_code() const noexcept; const char* name() const noexcept; - type_info(const type_info& rhs) = delete; // cannot be copied - type_info& operator=(const type_info& rhs) = delete; // cannot be copied + type_info(const type_info& rhs) = delete; // cannot be copied + type_info& operator=(const type_info& rhs) = delete; // cannot be copied }; } \end{codeblock} @@ -2769,7 +2955,7 @@ defines the type of objects thrown as exceptions by the implementation to report the execution of an invalid \indextext{cast!dynamic}% -\grammarterm{dynamic-cast} +\tcode{dynamic_cast} expression~(\ref{expr.dynamic.cast}). \indexlibrary{\idxcode{bad_cast}!constructor}% @@ -2836,7 +3022,7 @@ defines the type of objects thrown as exceptions by the implementation to report a null pointer in a -\grammarterm{typeid} +\tcode{typeid} expression~(\ref{expr.typeid}). \indexlibrary{\idxcode{bad_typeid}!constructor}% @@ -3361,7 +3547,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{remove_reference_t}. +Let \tcode{U} be \tcode{decay_t}. \pnum \requires \tcode{U} shall be \tcode{CopyConstructible}. @@ -3384,12 +3570,13 @@ \begin{itemdescr} \pnum \effects -If \tcode{E} is not a polymorphic class type, there is no effect. -Otherwise, if the static type or the dynamic type of \tcode{e} -is \tcode{nested_exception} or is publicly and unambiguously derived from -\tcode{nested_exception}, calls: +If \tcode{E} is not a polymorphic class type, or +if \tcode{nested_exception} is an inaccessible or ambiguous base class of \tcode{E}, +there is no effect. +Otherwise, performs: \begin{codeblock} -dynamic_cast(e).rethrow_nested(); +if (auto p = dynamic_cast(addressof(e))) + p->rethrow_nested(); \end{codeblock} \end{itemdescr} @@ -3400,6 +3587,8 @@ \pnum The header \tcode{} defines a class template and several support functions related to list-initialization~(see \ref{dcl.init.list}). +\indextext{signal-safe!\idxcode{initializer_list} functions}% +All functions specified in this subclause are signal-safe~(\ref{csignal.syn}). \rSec2[initializer_list.syn]{Header \tcode{} synopsis} \indexlibrary{\idxcode{initializer_list}}% @@ -3420,9 +3609,9 @@ constexpr initializer_list() noexcept; - constexpr size_t size() const noexcept; // number of elements - constexpr const E* begin() const noexcept; // first element - constexpr const E* end() const noexcept; // one past the last element + constexpr size_t size() const noexcept; // number of elements + constexpr const E* begin() const noexcept; // first element + constexpr const E* end() const noexcept; // one past the last element }; // \ref{support.initlist.range}, initializer list range access @@ -3538,11 +3727,9 @@ Headers \tcode{} (nonlocal jumps), \tcode{} (signal handling), -\tcode{ (alignment),} \tcode{} (variable arguments), -\tcode{} (\xname{bool_true_false_are_defined}), and -\tcode{} (runtime environment \tcode{getenv(), system()}), +\tcode{} (runtime environment \tcode{getenv, system}), provide further compatibility with C code. \pnum @@ -3562,7 +3749,7 @@ may introduce a data race with other calls to the \tcode{setlocale} function or with calls to functions that are affected by the current C locale. The implementation shall behave as if no -library function other than \tcode{locale::global()} calls the \tcode{setlocale} +library function other than \tcode{locale::global} calls the \tcode{setlocale} function. \rSec2[cstdarg.syn]{Header \tcode{} synopsis} @@ -3592,14 +3779,14 @@ 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()} +\tcode{va_start} macro in header \indexlibrary{\idxhdr{stdarg.h}}% \tcode{} are different in this International Standard. The parameter \tcode{parmN} -is the identifier of the rightmost parameter in the variable parameter list +is the rightmost parameter in the variable parameter list of the function definition (the one just before the \tcode{...}).\footnote{Note that \tcode{va_start} @@ -3607,6 +3794,9 @@ \tcode{operator\&} is overloaded for the type of \tcode{parmN}.} +If the parameter \tcode{parmN} is a pack expansion~(\ref{temp.variadic}) or +an entity resulting from a lambda capture~(\ref{expr.prim.lambda}), +the program is ill-formed, no diagnostic required. If the parameter \tcode{parmN} is of a reference type, or of a type that is not compatible with the @@ -3649,45 +3839,6 @@ \xref ISO C~7.13. -\rSec2[cstdbool.syn]{Header \tcode{} synopsis} - -\indextext{\idxhdr{cstdbool}}% -\indexlibrary{\idxhdr{cstdbool}}% -\indexlibrary{\idxcode{__bool_true_false_are_defined}}% -\begin{codeblock} -#define @\xname{bool_true_false_are_defined}@ 1 -\end{codeblock} - -\pnum -\indextext{\idxhdr{stdbool.h}}% -\indexlibrary{\idxhdr{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 -define macros named \tcode{bool}, \tcode{true}, or \tcode{false}. - -\xref ISO C~7.18. - -\rSec2[cstdalign.syn]{Header \tcode{} synopsis} - -\indexlibrary{\idxcode{__alignas_is_defined}}% -\indextext{\idxhdr{cstdalign}}% -\indexlibrary{\idxhdr{cstdalign}}% -\begin{codeblock} -#define @\xname{alignas_is_defined}@ 1 -\end{codeblock} - -\pnum -\indexlibrary{\idxhdr{cstdalign}}% -\indextext{\idxhdr{stdalign.h}}% -\indexlibrary{\idxhdr{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 -define a macro named \tcode{alignas}. - -\xref ISO C~7.15. - \rSec2[csignal.syn]{Header \tcode{} synopsis} \indextext{\idxhdr{csignal}}% @@ -3708,6 +3859,7 @@ namespace std { using sig_atomic_t = @\seebelow@; + // \ref{support.signal}, signal handlers extern "C" using @\placeholdernc{signal-handler}@ = void(int); // \expos @\placeholder{signal-handler}@* signal(int sig, @\placeholder{signal-handler}@* func); @@ -3731,32 +3883,76 @@ The contents of the header \tcode{} are the same as the C standard library header \tcode{}. +\rSec2[support.signal]{Signal handlers} + \pnum A call to the function \tcode{signal} synchronizes with any resulting invocation of the signal handler so installed. \pnum -The common subset of the C and \Cpp languages consists of all declarations, -definitions, and expressions that may appear in a well formed \Cpp program -and also in a conforming C program. -A -\indextext{POF}% -\indextext{function!plain old}% -POF (``plain old function'') is a function that uses only features from -this common subset, and that does not directly or indirectly use any -function that is not a POF, except that it may use -plain lock-free atomic operations. -A \term{plain lock-free atomic operation} is an invocation of a function -\placeholder{f} from Clause~\ref{atomics}, such that \placeholder{f} is not a -member function, and either \placeholder{f} is the function -\tcode{atomic_is_lock_free}, or for every atomic argument \tcode{A} passed to -\placeholder{f}, \tcode{atomic_is_lock_free(A)} yields \tcode{true}. -All signal handlers shall have C linkage. -The behavior of any function other than a POF used as a signal handler in a -\Cpp program is \impldef{use of non-POF function as signal handler}.\footnote{In -particular, a signal handler using exception handling is very likely to -have problems. Also, invoking \tcode{std::exit} may cause destruction of objects, -including those of the standard library implementation, which, in general, yields -undefined behavior in a signal handler (see~\ref{intro.execution}).} +A \defn{plain lock-free atomic operation} is +an invocation of a function \tcode{f} from Clause~\ref{atomics}, +such that: + +\begin{itemize} +\item +\tcode{f} is the function \tcode{atomic_is_lock_free()}, or + +\item +\tcode{f} is the member function \tcode{is_lock_free()}, or + +\item +\tcode{f} is a non-static member function invoked on an object \tcode{A}, +such that \tcode{A.is_lock_free()} yields \tcode{true}, or + +\item +\tcode{f} is a non-member function, and +for every pointer-to-atomic argument \tcode{A} passed to \tcode{f}, +\tcode{atomic_is_lock_free(A)} yields \tcode{true}. +\end{itemize} + +\pnum +\indextext{signal-safe!evaluation|see{evaluation, signal-safe}}% +An evaluation is \defnx{signal-safe}{evaluation!signal-safe} unless it includes one of the following: + +\begin{itemize} +\item +a call to any standard library function, +except for plain lock-free atomic operations and +functions explicitly identified as signal-safe. +\begin{note} +This implicitly excludes the use of \tcode{new} and \tcode{delete} expressions +that rely on a library-provided memory allocator. +\end{note} + +\item +an access to an object with thread storage duration; + +\item +a \tcode{dynamic_cast} expression; + +\item +throwing of an exception; + +\item +control entering a \grammarterm{try-block} or \grammarterm{function-try-block}; + +\item +initialization of a variable with static storage duration +requiring dynamic initialization~(\ref{basic.start.dynamic}, \ref{stmt.dcl})% +\footnote{Such initialization might occur because it is the first odr-use~(\ref{basic.def.odr}) of that variable.}; or + +\item +waiting for the completion of the initialization of a variable with static storage duration~(\ref{stmt.dcl}). +\end{itemize} + +A signal handler invocation has undefined behavior if it includes +an evaluation that is not signal-safe. + +\pnum +\indextext{signal-safe!\idxcode{signal}}% +The function \tcode{signal} is signal-safe if it is invoked +with the first argument equal to the signal number +corresponding to the signal that caused the invocation of the handler. \xref ISO C~7.14. diff --git a/source/tables.tex b/source/tables.tex index 0119f4fe4e..5dc258ec21 100644 --- a/source/tables.tex +++ b/source/tables.tex @@ -91,9 +91,9 @@ { \begin{floattablebase}{#1}{#2}{cc|cc|cc}{htbp} \topline - #3 & #4 & - #3 & #4 & - #3 & #4 \\ \capsep + \hdstyle{#3} & \hdstyle{#4} & + \hdstyle{#3} & \hdstyle{#4} & + \hdstyle{#3} & \hdstyle{#4} \\ \capsep } { \end{floattablebase} diff --git a/source/templates.tex b/source/templates.tex index b3834151ea..bac69bb1c5 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -146,7 +146,7 @@ in a templated entity, \item a member of a templated entity, \item an enumerator for an enumeration that is a templated entity, or -\item the closure type of a \grammarterm{lambda-expression}~(\ref{expr.prim.lambda}) +\item the closure type of a \grammarterm{lambda-expression}~(\ref{expr.prim.lambda.closure}) appearing in the declaration of a templated entity. \end{itemize} @@ -217,24 +217,23 @@ and template \grammarterm{template-argument}{s} are treated as types for descriptive purposes, the terms -\grammarterm{non-type parameter} +\term{non-type parameter} and -\grammarterm{non-type argument} +\term{non-type argument} are used to refer to non-type, non-template parameters and arguments.} \grammarterm{parameter-declaration}. A \grammarterm{template-parameter} of the form \tcode{class} \grammarterm{identifier} is a \grammarterm{type-parameter}. \begin{example} \begin{codeblock} - class T { @\commentellip@ }; - int i; +class T { @\commentellip@ }; +int i; - template void f(T t) { - T t1 = i; // template-parameters \tcode{T} and \tcode{i} - ::T t2 = ::i; // global namespace members \tcode{T} and \tcode{i} - } +template void f(T t) { + T t1 = i; // template-parameters \tcode{T} and \tcode{i} + ::T t2 = ::i; // global namespace members \tcode{T} and \tcode{i} +} \end{codeblock} - Here, the template \tcode{f} has a \grammarterm{type-parameter} called \tcode{T}, rather than an unnamed non-type \grammarterm{template-parameter} of class \tcode{T}. @@ -303,7 +302,7 @@ \grammarterm{template-argument}{s}~(\ref{temp.arg}). \end{note} The top-level -\grammarterm{cv-qualifiers} +\grammarterm{cv-qualifier}{s} on the \grammarterm{template-parameter} are ignored when determining its type. @@ -378,7 +377,7 @@ in a \grammarterm{template-parameter}. A default -\grammarterm{tem\-plate-argument} +\grammarterm{template-argument} may be specified for any kind of \grammarterm{template-parameter} (type, non-type, template) @@ -448,11 +447,11 @@ \begin{example} \begin{codeblock} -template class B; // error +template class B; // error // \tcode{U} can be neither deduced from the parameter-type-list nor specified -template void f() { } // error -template void g() { } // error +template void f() { } // error +template void g() { } // error \end{codeblock} \end{example} @@ -465,7 +464,7 @@ \begin{codeblock} template class X; -template class X { @\commentellip@ }; // error +template class X { @\commentellip@ }; // error \end{codeblock} \end{example} @@ -632,39 +631,36 @@ \begin{codeblock} template class X { @\commentellip@ }; -X< 1>2 > x1; // syntax error -X<(1>2)> x2; // OK +X< 1>2 > x1; // syntax error +X<(1>2)> x2; // OK template class Y { @\commentellip@ }; -Y> x3; // OK, same as \tcode{Y > x3;} -Y>1>> x4; // syntax error -Y>1)>> x5; // OK +Y> x3; // OK, same as \tcode{Y > x3;} +Y>1>> x4; // syntax error +Y>1)>> x5; // OK \end{codeblock} \end{example} \pnum -When the name of a member template specialization appears after -\tcode{.} -or -\tcode{->} -in a -\grammarterm{postfix-expression} -or after a -\grammarterm{nested-name-specifier} -in a -\grammarterm{qualified-id}, -and the -object expression of the -\grammarterm{postfix-expression} -is type-dependent -or -the \grammarterm{nested-name-specifier} in the -\grammarterm{qualified-id} -refers to a dependent type, but the name is not -a member of the current instantiation~(\ref{temp.dep.type}), -the member template name must be prefixed by the keyword -\tcode{template}. -Otherwise the name is assumed to name a non-template. +The keyword \tcode{template} is said to appear at the top level in +a \grammarterm{qualified-id} +if it appears outside of a \grammarterm{template-argument-list} or +\grammarterm{decltype-specifier}. +In a \grammarterm{qualified-id} of a \grammarterm{declarator-id} or +in a \grammarterm{qualified-id} formed by a \grammarterm{class-head-name} (Clause~\ref{class}) or +\grammarterm{enum-head-name}~(\ref{dcl.enum}), +the keyword \tcode{template} shall not appear at the top level. +In a \grammarterm{qualified-id} used as the name in a +\grammarterm{typename-specifier}~(\ref{temp.res}), +\grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}), +\grammarterm{using-declaration}~(\ref{namespace.udecl}), or +\grammarterm{class-or-decltype} (Clause~\ref{class.derived}), +an optional keyword \tcode{template} appearing at the top level is ignored. +In these contexts, a \tcode{<} token is always assumed to introduce a +\grammarterm{template-argument-list}. +In all other contexts, when naming a template specialization of +a member of an unknown specialization~(\ref{temp.dep.type}), +the member template name shall be prefixed by the keyword \tcode{template}. \begin{example} \begin{codeblock} @@ -673,10 +669,10 @@ template static X* adjust(); }; template void f(T* p) { - T* p1 = p->alloc<200>(); // ill-formed: \tcode{<} means less than - T* p2 = p->template alloc<200>(); // OK: \tcode{<} starts template argument list - T::adjust<100>(); // ill-formed: \tcode{<} means less than - T::template adjust<100>(); // OK: \tcode{<} starts template argument list + T* p1 = p->alloc<200>(); // ill-formed: \tcode{<} means less than + T* p2 = p->template alloc<200>(); // OK: \tcode{<} starts template argument list + T::adjust<100>(); // ill-formed: \tcode{<} means less than + T::template adjust<100>(); // OK: \tcode{<} starts template argument list } \end{codeblock} \end{example} @@ -684,7 +680,8 @@ \pnum A name prefixed by the keyword \tcode{template} -shall be a \grammarterm{template-id} or the name shall refer to a class template. +shall be a \grammarterm{template-id} or +the name shall refer to a class template or an alias template. \begin{note} The keyword \tcode{template} @@ -715,8 +712,8 @@ template void f(T t) { A a; - a.template f<>(t); // OK: calls template - a.template f(t); // error: not a \grammarterm{template-id} + a.template f<>(t); // OK: calls template + a.template f(t); // error: not a \grammarterm{template-id} } template struct B { @@ -870,7 +867,7 @@ In that case the empty \tcode{<>} brackets shall still be used as the -\grammarterm{template-argument-list.} +\grammarterm{template-argument-list}. \begin{example} \begin{codeblock} @@ -1126,8 +1123,8 @@ \grammarterm{template-parameter} is instantiated. If a specialization is not visible at the point of instantiation, -and it would have been selected had it been visible, the program is ill-formed; -no diagnostic is required. +and it would have been selected had it been visible, the program is ill-formed, +no diagnostic required. \begin{example} \begin{codeblock} @@ -1141,10 +1138,8 @@ V y; V z; }; -C c; // \tcode{V} within \tcode{C} uses the primary template, - // so \tcode{c.y.x} has type \tcode{int} - // \tcode{V} within \tcode{C} uses the partial specialization, - // so \tcode{c.z.x} has type \tcode{long} +C c; // \tcode{V} within \tcode{C} uses the primary template, so \tcode{c.y.x} has type \tcode{int} + // \tcode{V} within \tcode{C} uses the partial specialization, so \tcode{c.z.x} has type \tcode{long} \end{codeblock} \end{example} @@ -1154,7 +1149,7 @@ 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-parameter-list} 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~(\ref{temp.over.link}), and for template \grammarterm{template-parameter}{s}, @@ -1614,8 +1609,8 @@ template void f(T2); }; -template <> void A::f(int) { } // non-template member function -template <> template <> void A::f<>(int) { } // member function template specialization +template <> void A::f(int) { } // non-template member function +template <> template <> void A::f<>(int) { } // member function template specialization int main() { A ac; @@ -1632,8 +1627,8 @@ \begin{codeblock} template struct AA { - template virtual void g(C); // error - virtual void f(); // OK + template virtual void g(C); // error + virtual void f(); // OK }; \end{codeblock} \end{example} @@ -1725,7 +1720,7 @@ Tuple<> t0; // \tcode{Types} contains no arguments Tuple t1; // \tcode{Types} contains one argument: \tcode{int} Tuple t2; // \tcode{Types} contains two arguments: \tcode{int} and \tcode{float} -Tuple<0> error; // error: 0 is not a type +Tuple<0> error; // error: \tcode{0} is not a type \end{codeblock} \end{example} @@ -1902,8 +1897,8 @@ X x(values...); } -template void f<>(); // OK: \tcode{X<>} has no base classes - // \tcode{x} is a variable of type \tcode{X<>} that is value-initialized +template void f<>(); // OK: \tcode{X<>} has no base classes + // \tcode{x} is a variable of type \tcode{X<>} that is value-initialized \end{codeblock} \end{example} @@ -2099,14 +2094,6 @@ \end{codeblock} \end{example} -\pnum -When a function is defined in a friend function declaration in a class -template, the function is instantiated when the function is -odr-used~(\ref{basic.def.odr}). The -same restrictions on multiple declarations and definitions that apply -to non-template function declarations and definitions also apply to -these implicit definitions. - \pnum A member of a class template may be declared to be a friend of a non-template class. @@ -2141,12 +2128,12 @@ }; class C { - template friend struct A::B; // grants friendship to \tcode{A::B} even though - // 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 struct A::B; // grants friendship to \tcode{A::B} even though + // 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} }; \end{codeblock} \end{example} @@ -2166,7 +2153,7 @@ \begin{codeblock} template class A { }; class X { - template friend class A; // error + template friend class A; // error }; \end{codeblock} \end{example} @@ -2181,9 +2168,9 @@ \pnum \indextext{specialization!class template partial}% -\indextext{template!primary}% +\indextext{primary class template|see{template, primary}}% A -\defnx{primary class template}{see{template, primary}} +\defnx{primary class template}{template!primary} declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a @@ -2246,28 +2233,30 @@ For example, \begin{codeblock} -template class A { }; // error +template +class A { }; // error \end{codeblock} \end{note} \pnum -A class template partial specialization may be declared or redeclared in any -namespace scope in which the corresponding primary template -may be defined~(\ref{namespace.memdef} and~\ref{temp.mem}). +A class template partial specialization may be declared in any +scope in which the corresponding primary template +may be defined~(\ref{namespace.memdef}, \ref{class.mem}, \ref{temp.mem}). \begin{example} \begin{codeblock} template struct A { struct C { template struct B { }; + template struct B { }; // partial specialization \#1 }; }; // partial specialization of \tcode{A::C::B} template template - struct A::C::B { }; + struct A::C::B { }; // \#2 -A::C::B absip; // uses partial specialization +A::C::B absip; // uses partial specialization \#2 \end{codeblock} \end{example} @@ -2285,17 +2274,17 @@ \begin{codeblock} namespace N { - template class A { }; // primary template + template class A { }; // primary template } -using N::A; // refers to the primary template +using N::A; // refers to the primary template namespace N { - template class A { }; // partial specialization + template class A { }; // partial specialization } -A a; // uses the partial specialization, which is found through - // the using declaration which refers to the primary template +A a; // uses the partial specialization, which is found through the using-declaration + // which refers to the primary template \end{codeblock} \end{example} @@ -2316,11 +2305,11 @@ \begin{codeblock} template struct C {}; -template struct C; // error +template struct C; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; -template< int X > class A { }; // error +template< int X > class A { }; // error \end{codeblock} \end{example} @@ -2370,7 +2359,6 @@ list if the template arguments of the partial specialization can be deduced from the actual template argument list~(\ref{temp.deduct}). \begin{example} - \begin{codeblock} template class A { }; // \#1 template class A { }; // \#2 @@ -2441,18 +2429,18 @@ \begin{example} \begin{codeblock} template class X { }; -template class X { }; // \#1 -template class X { }; // \#2 +template class X { }; // \#1 +template class X { }; // \#2 -template void f(X); // A -template void f(X); // B +template void f(X); // A +template void f(X); // B template class Y { }; -template class Y

{ }; // \#3 -template class Y { }; // \#4 +template class Y

{ }; // \#3 +template class Y { }; // \#4 -template void g(Y); // C -template void g(Y); // D +template void g(Y); // C +template void g(Y); // D \end{codeblock} According to the ordering rules for function templates, @@ -2493,11 +2481,12 @@ \begin{example} \begin{codeblock} -// primary template +// primary class template template struct A { void f(); }; +// member of primary class template template void A::f() { } // class template partial specialization @@ -2621,7 +2610,7 @@ \pnum The signature of a function template -is defined in~\ref{intro.defs}. +is defined in Clause~\ref{intro.defs}. The names of the template parameters are significant only for establishing the relationship between the template parameters and the rest of the signature. @@ -2692,7 +2681,7 @@ // was not in scope at the first declaration of \tcode{h()} \end{codeblock} \end{example} -\indextext{equivalent!functionally|see{expression, functionally equivalent}}% +\indextext{equivalent!functionally!expression|see{expression, functionally equivalent}}% \indextext{functionally equivalent!expression|see{expression, functionally equivalent}}% Two expressions involving template parameters that are not equivalent are \defnx{functionally equivalent}{expression!functionally equivalent} @@ -2708,7 +2697,7 @@ lists that are equivalent using the rules described above to compare expressions involving template parameters. -\indextext{equivalent!functionally|see{template, function, functionally equivalent}}% +\indextext{equivalent!functionally!function template|see{template, function, functionally equivalent}}% \indextext{functionally equivalent!function template|see{template, function, functionally equivalent}}% Two function templates are \defnx{functionally equivalent}{template!function!functionally equivalent} @@ -2719,8 +2708,8 @@ compare expressions involving template parameters. If a program contains declarations of function templates that are -functionally equivalent but not equivalent, the program is ill-formed; -no diagnostic is required. +functionally equivalent but not equivalent, the program is ill-formed, +no diagnostic required. \pnum \begin{note} @@ -3092,9 +3081,7 @@ \pnum A qualified name used as the name in a -\grammarterm{mem-initializer-id}, -a -\grammarterm{base-specifier}, +\grammarterm{class-or-decltype} (Clause~\ref{class.derived}) or an \grammarterm{elaborated-type-specifier} is implicitly assumed to name a type, without the use of the @@ -3567,9 +3554,9 @@ template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names. An expressions may be -\grammarterm{type-dependent} +\defnx{type-dependent}{expression!type-dependent} (that is, its type may depend on a template parameter) or -\grammarterm{value-dependent} +\defnx{value-dependent}{expression!value-dependent} (that is, its value when evaluated as a constant expression~(\ref{expr.const}) may depend on a template parameter) as described in this subclause. @@ -3590,7 +3577,7 @@ if \begin{itemize} -\item +\item any of the expressions in the \grammarterm{expression-list} is a pack expansion~(\ref{temp.variadic}), @@ -3763,8 +3750,7 @@ class B { B* p1; // \tcode{B} is the current instantiation A::B* p2; // \tcode{A::B} is the current instantiation - typename A::B* p3; // \tcode{A::B} is not the - // current instantiation + typename A::B* p3; // \tcode{A::B} is not the current instantiation }; }; @@ -3878,7 +3864,7 @@ if it is \begin{itemize} -\item +\item A \grammarterm{qualified-id} in which the @@ -3975,6 +3961,8 @@ an array type whose element type is dependent or whose bound (if any) is value-dependent, \item +a function type whose exception specification is value-dependent, +\item a \grammarterm{simple-template-id} in which either the template name is a template parameter or any of the @@ -4033,9 +4021,9 @@ with a return type that contains a placeholder type, \item -an \grammarterm{identifier} associated by name lookup with a decomposition -declaration~(\ref{dcl.decomp}) whose \grammarterm{brace-or-equal-initializer} -is type-dependent, +an \grammarterm{identifier} associated by name lookup with +a structured binding declaration~(\ref{dcl.struct.bind}) whose +\grammarterm{brace-or-equal-initializer} is type-dependent, \item the @@ -4559,7 +4547,7 @@ static T t; }; typedef int function(); -A a; // ill-formed: would declare \tcode{A::t} as a static member function +A a; // ill-formed: would declare \tcode{A::t} as a static member function \end{codeblock} \end{example} @@ -4617,15 +4605,23 @@ part of the instantiation of the entity within which the local class or enumeration is declared. \end{note} + +\pnum The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, -default arguments, or \grammarterm{noexcept-specifier}{s} of the class member functions, -member classes, scoped member enumerations, static data members and member templates; and it causes the -implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions. +default arguments, or \grammarterm{noexcept-specifier}{s} of the +class member functions, +member classes, +scoped member enumerations, +static data members, +member templates, and +friends; and +it causes the implicit instantiation of the definitions of +unscoped member enumerations and member anonymous unions. However, for the purpose of determining whether an instantiated redeclaration -of a member is valid according to~\ref{class.mem}, a declaration that -corresponds to a definition in the template is considered to be a -definition. +is valid according to~\ref{basic.def.odr} and \ref{class.mem}, +a declaration that corresponds to a definition in the template +is considered to be a definition. \begin{example} \begin{codeblock} template @@ -4643,6 +4639,14 @@ but noted as being associated with a definition in \tcode{Outer}.) \#2 is also a redeclaration of \#1a. It is noted as associated with a definition, so it is an invalid redeclaration of the same partial specialization. + +\begin{codeblock} +template struct Friendly { + template friend int f(U) { return sizeof(T); } +}; +Friendly fc; +Friendly ff; // ill-formed: produces second definition of \tcode{f(U)} +\end{codeblock} \end{example} \pnum @@ -4661,6 +4665,9 @@ the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. +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. 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 @@ -4796,7 +4803,7 @@ the same template parameters and the same access as that of the function template \tcode{f} used at that point, except that the scope in which a closure type is -declared~(\ref{expr.prim.lambda}) -- and therefore its associated namespaces -- +declared~(\ref{expr.prim.lambda.closure}) -- and therefore its associated namespaces -- remain as determined from the context of the definition for the default argument. This analysis is called @@ -4977,11 +4984,10 @@ template class Y { void mf() { } }; } -template class Y; // error: class template \tcode{Y} not visible in the global namespace +template class Y; // error: class template \tcode{Y} not visible in the global namespace using N::Y; -template class Y; // error: explicit instantiation outside of the - // namespace of the template +template class Y; // error: explicit instantiation outside of the namespace of the template template class N::Y; // OK: explicit instantiation in namespace \tcode{N} template void N::Y::mf(); // OK: explicit instantiation in namespace \tcode{N} @@ -4995,12 +5001,11 @@ specialization or of a member function template specialization provided it can be deduced from the type of a function parameter~(\ref{temp.deduct}). \begin{example} - \begin{codeblock} template class Array { @\commentellip@ }; template void sort(Array& v) { @\commentellip@ } -// instantiate \tcode{sort(Array\&)} - template-argument deduced +// instantiate \tcode{sort(Array\&)} -- template-argument deduced template void sort<>(Array&); \end{codeblock} \end{example} @@ -5143,14 +5148,9 @@ \end{example} \pnum -An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization -whose \grammarterm{declarator-id} or \grammarterm{class-head-name} is not qualified -shall be declared in the nearest enclosing namespace of the template, -or, if the namespace is inline~(\ref{namespace.def}), any namespace from its enclosing namespace set. -Such a declaration may also be a definition. -If the declaration is not a definition, the specialization may be -defined later~(\ref{namespace.memdef}). +may be declared in any scope in which the corresponding primary template +may be defined~(\ref{namespace.memdef}, \ref{class.mem}, \ref{temp.mem}). \pnum A declaration of a function template, class template, or variable template being explicitly @@ -5400,9 +5400,9 @@ that requires default-initialization must use a \grammarterm{braced-init-list}: \begin{codeblock} -template<> X Q::x; // declaration -template<> X Q::x (); // error: declares a function -template<> X Q::x { }; // definition +template<> X Q::x; // declaration +template<> X Q::x (); // error: declares a function +template<> X Q::x { }; // definition \end{codeblock} \end{note} @@ -5584,17 +5584,14 @@ \grammarterm{template-argument}{s} are specified in uses of a class template specialization. \begin{example} - \begin{codeblock} template void sort(Array& v); void f(Array& cv, Array& ci) { - sort(cv); // \tcode{sort(Array\&)} - sort(ci); // \tcode{sort(Array\&)} + sort(cv); // \tcode{sort(Array\&)} + sort(ci); // \tcode{sort(Array\&)} } \end{codeblock} - and - \begin{codeblock} template U convert(V v); @@ -5608,7 +5605,6 @@ \pnum A template argument list may be specified when referring to a specialization of a function template - \begin{itemize} \item when a function is called, @@ -5642,20 +5638,17 @@ \grammarterm{template-id} is an lvalue for the function template specialization. \begin{example} - \begin{codeblock} template X f(Y); template X g(Y); void h() { int i = f(5.6); // \tcode{Y} is deduced to be \tcode{double} int j = f(5.6); // ill-formed: \tcode{X} cannot be deduced - f(f); // \tcode{Y} for outer \tcode{f} deduced to be - // \tcode{int (*)(bool)} - f(f); // ill-formed: \tcode{f} does not denote a - // single function template specialization + f(f); // \tcode{Y} for outer \tcode{f} deduced to be \tcode{int (*)(bool)} + f(f); // ill-formed: \tcode{f} does not denote a single function template specialization int k = g(5.6); // \tcode{Y} is deduced to be double, \tcode{Z} is deduced to an empty sequence - f(g); // \tcode{Y} for outer \tcode{f} is deduced to be - // \tcode{int (*)(bool)}, \tcode{Z} is deduced to an empty sequence + f(g); // \tcode{Y} for outer \tcode{f} is deduced to be \tcode{int (*)(bool)}, + // \tcode{Z} is deduced to an empty sequence } \end{codeblock} \end{example} @@ -5692,9 +5685,8 @@ template void f2(); void g() { f("aa",3.0); - f("aa",3.0); // \tcode{Z} is deduced to be \tcode{double} - f("aa",3.0); // \tcode{Y} is deduced to be \tcode{const char*}, and - // \tcode{Z} is deduced to be \tcode{double} + f("aa",3.0); // \tcode{Z} is deduced to be \tcode{double} + f("aa",3.0); // \tcode{Y} is deduced to be \tcode{const char*}, and \tcode{Z} is deduced to be \tcode{double} f("aa",3.0); // error: \tcode{X} cannot be deduced f2(); // OK } @@ -5720,7 +5712,7 @@ }; void g() { - f(1); // OK, means \tcode{f(Complex(1))} + f(1); // OK, means \tcode{f(Complex(1))} } \end{codeblock} \end{note} @@ -5763,13 +5755,11 @@ 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 + 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 + 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} @@ -5892,7 +5882,7 @@ the type of the function template for template argument deduction. If a template argument has not been deduced and its corresponding template parameter has a default argument, the -template argument is determined by substituting the template +template argument is determined by substituting the template arguments determined for preceding template parameters into the default argument. If the substitution results in an invalid type, as described above, type deduction fails. @@ -5947,8 +5937,8 @@ template void g(...) { } void h() { - f(0); // OK, substituting return type causes deduction to fail - g(0); // error, substituting parameter type instantiates \tcode{A} + f(0); // OK, substituting return type causes deduction to fail + g(0); // error, substituting parameter type instantiates \tcode{A} } \end{codeblock} \end{example} @@ -5974,11 +5964,11 @@ Y(X){} }; -template auto f(T t1, T t2) -> decltype(t1 + t2); // \#1 -X f(Y, Y); // \#2 +template auto f(T t1, T t2) -> decltype(t1 + t2); // \#1 +X f(Y, Y); // \#2 X x1, x2; -X x3 = f(x1, x2); // deduction fails on \#1 (cannot add \tcode{X+X}), calls \#2\end{codeblock} +X x3 = f(x1, x2); // deduction fails on \#1 (cannot add \tcode{X+X}), calls \#2\end{codeblock} \end{example} \begin{note} Type deduction may fail for @@ -6038,10 +6028,10 @@ int main() { // Deduction fails in each of these cases: - f(0); // \tcode{A} does not contain a member \tcode{Y} - f(0); // The \tcode{Y} member of \tcode{B} is not a type - g(0); // The \tcode{N} member of \tcode{C} is not a non-type - h(0); // The \tcode{TT} member of \tcode{D} is not a template + f(0); // \tcode{A} does not contain a member \tcode{Y} + f(0); // The \tcode{Y} member of \tcode{B} is not a type + g(0); // The \tcode{N} member of \tcode{C} is not a non-type + h(0); // The \tcode{TT} member of \tcode{D} is not a template } \end{codeblock} \end{example} @@ -6108,8 +6098,8 @@ \begin{codeblock} template int f(int); template int f(int); -int i1 = f<1000>(0); // OK -int i2 = f<1>(0); // ambiguous; not narrowing +int i1 = f<1000>(0); // OK +int i2 = f<1>(0); // ambiguous; not narrowing \end{codeblock} \end{example} @@ -6138,28 +6128,28 @@ \begin{example} \begin{codeblock} template void f(std::initializer_list); -f({1,2,3}); // \tcode{T} deduced to \tcode{int} -f({1,"asdf"}); // error: \tcode{T} deduced to both \tcode{int} and \tcode{const char*} +f({1,2,3}); // \tcode{T} deduced to \tcode{int} +f({1,"asdf"}); // error: \tcode{T} deduced to both \tcode{int} and \tcode{const char*} template void g(T); -g({1,2,3}); // error: no argument deduced for \tcode{T} +g({1,2,3}); // error: no argument deduced for \tcode{T} template void h(T const(&)[N]); -h({1,2,3}); // \tcode{T} deduced to \tcode{int}, \tcode{N} deduced to \tcode{3} +h({1,2,3}); // \tcode{T} deduced to \tcode{int}, \tcode{N} deduced to \tcode{3} template void j(T const(&)[3]); -j({42}); // \tcode{T} deduced to \tcode{int}, array bound not considered +j({42}); // \tcode{T} deduced to \tcode{int}, array bound not considered struct Aggr { int i; int j; }; template void k(Aggr const(&)[N]); -k({1,2,3}); // error: deduction fails, no conversion from \tcode{int} to \tcode{Aggr} -k({{1},{2},{3}}); // OK, \tcode{N} deduced to \tcode{3} +k({1,2,3}); // error: deduction fails, no conversion from \tcode{int} to \tcode{Aggr} +k({{1},{2},{3}}); // OK, \tcode{N} deduced to \tcode{3} template void m(int const(&)[M][N]); -m({{1,2},{3,4}}); // \tcode{M} and \tcode{N} both deduced to \tcode{2} +m({{1,2},{3,4}}); // \tcode{M} and \tcode{N} both deduced to \tcode{2} template void n(T const(&)[N], T); -n({{1},{2},{3}},Aggr()); // OK, \tcode{T} is \tcode{Aggr}, \tcode{N} is \tcode{3} +n({{1},{2},{3}},Aggr()); // OK, \tcode{T} is \tcode{Aggr}, \tcode{N} is \tcode{3} \end{codeblock} \end{example} For a function parameter pack that occurs at the end @@ -6174,7 +6164,6 @@ context~(\ref{temp.deduct.type}), the type of that parameter pack is never deduced. \begin{example} - \begin{codeblock} template void f(Types& ...); template void g(T1, Types ...); @@ -6182,14 +6171,12 @@ void h(int x, float& y) { const int z = x; - f(x, y, z); // \tcode{Types} is deduced to \tcode{int}, \tcode{float}, \tcode{const int} - g(x, y, z); // \tcode{T1} is deduced to \tcode{int}; \tcode{Types} is deduced to \tcode{float}, \tcode{int} - g1(x, y, z); // error: \tcode{Types} is not deduced - g1(x, y, z); // OK, no deduction occurs - + f(x, y, z); // \tcode{Types} is deduced to \tcode{int}, \tcode{float}, \tcode{const int} + g(x, y, z); // \tcode{T1} is deduced to \tcode{int}; \tcode{Types} is deduced to \tcode{float}, \tcode{int} + g1(x, y, z); // error: \tcode{Types} is not deduced + g1(x, y, z); // OK, no deduction occurs } \end{codeblock} - \end{example} \pnum @@ -6263,17 +6250,17 @@ template struct A { template - A(T&&, U&&, int*); // \#1: \tcode{T\&\&} is not a forwarding reference. - // \tcode{U\&\&} is a forwarding reference. - A(T&&, int*); // \#2 + A(T&&, U&&, int*); // \#1: \tcode{T\&\&} is not a forwarding reference. + // \tcode{U\&\&} is a forwarding reference. + A(T&&, int*); // \#2 }; -template A(T&&, int*) -> A; // \#3: \tcode{T\&\&} is a forwarding reference. +template A(T&&, int*) -> A; // \#3: \tcode{T\&\&} is a forwarding reference. int *ip; -A a{i, 0, ip}; // error: cannot deduce from \#1 -A a0{0, 0, ip}; // uses \#1 to deduce \tcode{A} and \#1 to initialize -A a2{i, ip}; // uses \#3 to deduce \tcode{A} and \#2 to initialize +A a{i, 0, ip}; // error: cannot deduce from \#1 +A a0{0, 0, ip}; // uses \#1 to deduce \tcode{A} and \#1 to initialize +A a2{i, ip}; // uses \#3 to deduce \tcode{A} and \#2 to initialize \end{codeblock} \end{example} @@ -6366,8 +6353,7 @@ \pnum \begin{example} \begin{codeblock} -// Only one function of an overload set matches the call so the function -// parameter is a deduced context. +// Only one function of an overload set matches the call so the function parameter is a deduced context. template int f(T (*p)(T)); int g(int); int g(char); @@ -6378,8 +6364,7 @@ \pnum \begin{example} \begin{codeblock} -// Ambiguous deduction causes the second function parameter to be a -// non-deduced context. +// Ambiguous deduction causes the second function parameter to be a non-deduced context. template int f(T, T (*p)(T)); int g(int); char g(char); @@ -6390,8 +6375,7 @@ \pnum \begin{example} \begin{codeblock} -// The overload set contains a template, causing the second function -// parameter to be a non-deduced context. +// The overload set contains a template, causing the second function parameter to be a non-deduced context. template int f(T, T (*p)(T)); char g(char); template T g(T); @@ -6419,11 +6403,11 @@ template struct Z { typedef typename T::x xx; }; - template typename Z::xx f(void *, T); // \#1 - template void f(int, T); // \#2 + template typename Z::xx f(void *, T); // \#1 + template void f(int, T); // \#2 struct A {} a; int main() { - f(1, a); // OK, deduction fails for \#1 because there is no conversion from int to void* + f(1, a); // OK, deduction fails for \#1 because there is no conversion from \tcode{int} to \tcode{void*} } \end{codeblock} \end{example} @@ -6697,14 +6681,14 @@ as the type from the parameter template. \begin{example} \begin{codeblock} -template void f(Args... args); // \#1 -template void f(T1 a1, Args... args); // \#2 -template void f(T1 a1, T2 a2); // \#3 +template void f(Args... args); // \#1 +template void f(T1 a1, Args... args); // \#2 +template void f(T1 a1, T2 a2); // \#3 -f(); // calls \#1 -f(1, 2, 3); // calls \#2 -f(1, 2); // calls \#3; non-variadic template \#3 is more - // specialized than the variadic templates \#1 and \#2 +f(); // calls \#1 +f(1, 2, 3); // calls \#2 +f(1, 2); // calls \#3; non-variadic template \#3 is more specialized + // than the variadic templates \#1 and \#2 \end{codeblock} \end{example} @@ -6764,19 +6748,21 @@ \end{note} \begin{example} \begin{codeblock} -template T f(int); // \#1 -template T f(U); // \#2 +template T f(int); // \#1 +template T f(U); // \#2 void g() { - f(1); // calls \#1 + f(1); // calls \#1 } \end{codeblock} \end{example} \pnum -\begin{note} Partial ordering of function templates containing +\begin{note} +Partial ordering of function templates containing template parameter packs is independent of the number of deduced arguments -for those template parameter packs. \end{note} \begin{example} - +for those template parameter packs. +\end{note} +\begin{example} \begin{codeblock} template struct Tuple { }; template void g(Tuple); // \#1 @@ -6788,7 +6774,6 @@ g(Tuple()); // calls \#3 g(Tuple()); // calls \#3 \end{codeblock} - \end{example} \rSec3[temp.deduct.type]{Deducing template arguments from a type} @@ -6919,7 +6904,7 @@ g({1,2,3}); // error: no argument deduced for \tcode{T} \end{codeblock} \end{example} -\item A function parameter pack that does not occur at the end of the +\item A function parameter pack that does not occur at the end of the \grammarterm{parameter-declaration-list}. \end{itemize} @@ -7149,11 +7134,11 @@ \begin{example} \begin{codeblock} template void f(T&&); -template <> void f(int&) { } // \#1 -template <> void f(int&&) { } // \#2 +template <> void f(int&) { } // \#1 +template <> void f(int&&) { } // \#2 void g(int i) { - f(i); // calls \tcode{f(int\&)}, i.e., \#1 - f(0); // calls \tcode{f(int\&\&)}, i.e., \#2 + f(i); // calls \tcode{f(int\&)}, i.e., \#1 + f(0); // calls \tcode{f(int\&\&)}, i.e., \#2 } \end{codeblock} \end{example} @@ -7177,9 +7162,9 @@ \end{itemize} \begin{example} \begin{codeblock} -template void f(T*, U...) { } // \#1 -template void f(T) { } // \#2 -template void f(int*); // selects \#1 +template void f(T*, U...) { } // \#1 +template void f(T) { } // \#2 +template void f(int*); // selects \#1 \end{codeblock} \end{example} @@ -7234,8 +7219,8 @@ }; using R = long; -using R = C>::Q; // OK; \tcode{T} was deduced to \tcode{long} from the - // template argument value in the type \tcode{A<2>} +using R = C>::Q; // OK; \tcode{T} was deduced to \tcode{long} from the + // template argument value in the type \tcode{A<2>} \end{codeblock} \end{example} The type of \tcode{N} in the type \tcode{T[N]} is \tcode{std::size_t}. @@ -7247,7 +7232,7 @@ }; using V = decltype(sizeof 0); -using V = S::Q; // OK; \tcode{T} was deduced to \tcode{std::size_t} from the type \tcode{int[42]} +using V = S::Q; // OK; \tcode{T} was deduced to \tcode{std::size_t} from the type \tcode{int[42]} \end{codeblock} \end{example} @@ -7257,7 +7242,7 @@ template void f(int (&a)[i]); int v[10]; void g() { - f(v); // OK: \tcode{T} is \tcode{std::size_t} + f(v); // OK: \tcode{T} is \tcode{std::size_t} } \end{codeblock} \end{example} @@ -7266,7 +7251,6 @@ \begin{note} Except for reference and pointer types, a major array bound is not part of a function parameter type and cannot be deduced from an argument: - \begin{codeblock} template void f1(int a[10][i]); template void f2(int a[i][20]); @@ -7274,11 +7258,11 @@ void g() { int v[10][20]; - f1(v); // OK: \tcode{i} deduced to be \tcode{20} - f1<20>(v); // OK - f2(v); // error: cannot deduce template-argument \tcode{i} - f2<10>(v); // OK - f3(v); // OK: \tcode{i} deduced to be \tcode{10} + f1(v); // OK: \tcode{i} deduced to be \tcode{20} + f1<20>(v); // OK + f2(v); // error: cannot deduce template-argument \tcode{i} + f2<10>(v); // OK + f3(v); // OK: \tcode{i} deduced to be \tcode{10} } \end{codeblock} \end{note} @@ -7297,9 +7281,9 @@ void k() { A<1> a1; A<2> a2; - g(a1); // error: deduction fails for expression \tcode{i+1} - g<0>(a1); // OK - f(a1, a2); // OK + g(a1); // error: deduction fails for expression \tcode{i+1} + g<0>(a1); // OK + f(a1, a2); // OK } \end{codeblock} \end{example} @@ -7314,16 +7298,14 @@ \begin{codeblock} template T deduce(typename A::X x, // \tcode{T} is not deduced here - T t, // but \tcode{T} is deduced here - typename B::Y y); // \tcode{i} is not deduced here + T t, // but \tcode{T} is deduced here + typename B::Y y); // \tcode{i} is not deduced here A a; B<77> b; int x = deduce<77>(a.xm, 62, b.ym); -// \tcode{T} is deduced to be \tcode{int}, \tcode{a.xm} must be convertible to -// \tcode{A::X} -// \tcode{i} is explicitly specified to be \tcode{77}, \tcode{b.ym} must be convertible -// to \tcode{B<77>::Y} +// \tcode{T} is deduced to be \tcode{int}, \tcode{a.xm} must be convertible to \tcode{A::X} +// \tcode{i} is explicitly specified to be \tcode{77}, \tcode{b.ym} must be convertible to \tcode{B<77>::Y} \end{codeblock} \end{note} @@ -7423,10 +7405,12 @@ \end{example} \pnum -\begin{note} Template argument deduction involving parameter +\begin{note} +Template argument deduction involving parameter packs~(\ref{temp.variadic}) can deduce zero or more arguments for -each parameter pack. \end{note}\begin{example} - +each parameter pack. +\end{note} +\begin{example} \begin{codeblock} template struct X { }; template struct X { }; @@ -7444,7 +7428,6 @@ Y y3; // uses primary template; \tcode{Types} contains \tcode{int}, \tcode{float}, \tcode{double} int fv = f(g); // OK; \tcode{Types} contains \tcode{int}, \tcode{float} \end{codeblock} - \end{example} \rSec3[temp.deduct.decl]{Deducing template arguments from a function declaration} @@ -7634,7 +7617,7 @@ using type = short; operator type(); }; -S x{A()}; // \tcode{x} is of type \tcode{S} +S x{A()}; // \tcode{x} is of type \tcode{S} \end{codeblock} \end{example} @@ -7652,6 +7635,11 @@ A \grammarterm{deduction-guide} shall be declared in the same scope -as the corresponding class template. +as the corresponding class template +and, for a member class template, with the same access. +Two deduction guide declarations +in the same translation unit +for the same class template +shall not have equivalent \grammarterm{parameter-declaration-clause}{s}. \indextext{template|)} diff --git a/source/threads.tex b/source/threads.tex index 60bf10ee26..99dce2933b 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -156,6 +156,8 @@ \pnum The standard library templates \tcode{unique_lock}~(\ref{thread.lock.unique}), +\tcode{shared_lock}~(\ref{thread.lock.shared}), +\tcode{scoped_lock}~(\ref{thread.lock.scoped}), \tcode{lock_guard}~(\ref{thread.lock.guard}), \tcode{lock}, \tcode{try_lock}~(\ref{thread.lock.algorithm}), and \tcode{condition_variable_any}~(\ref{thread.condition.condvarany}) all operate on user-supplied @@ -270,9 +272,9 @@ \pnum In several places in this Clause the operation -\indextext{DECAY_COPY@\tcode{\textit{DECAY_COPY}}}% -\indexlibrary{DECAY_COPY@\tcode{\textit{DECAY_COPY}}}% -{\tcode{\textit{DECAY_COPY}(x)}} is used. All +\indextext{DECAY_COPY@\tcode{\placeholder{DECAY_COPY}}}% +\indexlibrary{DECAY_COPY@\tcode{\placeholder{DECAY_COPY}}}% +{\tcode{\placeholdernc{DECAY_COPY}(x)}} is used. All such uses mean call the function \tcode{decay_copy(x)} and use the result, where \tcode{decay_copy} is defined as follows: @@ -518,9 +520,13 @@ \pnum \requires\ \tcode{F} and each \tcode{Ti} in \tcode{Args} shall satisfy the \tcode{MoveConstructible} requirements. -\tcode{\textit{INVOKE}(\textit{DECAY_COPY}(} -\tcode{std::forward(f)), \textit{DECAY_COPY}(std::forward(args))...)}~(\ref{func.require}) shall be -a valid expression. +\tcode{% +\placeholdernc{INVOKE}(\brk{}% +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(f)), +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(\brk{}args))...)}~(\ref{func.require}) shall be +a va\-lid expression. \pnum \remarks @@ -529,15 +535,23 @@ \pnum \effects\ Constructs an object of type \tcode{thread}. The new thread of execution executes -\tcode{\textit{INVOKE}(\textit{DECAY_COPY}(}\ -\tcode{std::forward(f)), \textit{DECAY_COPY}(std::forward(args))...)} with the calls to -\brk{}\tcode{\textit{DECAY_COPY}} being evaluated in the constructing thread. Any return value from this invocation +\tcode{% +\placeholdernc{INVOKE}(\brk{}% +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(f)), +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(\brk{}args))...)} with the calls to +\tcode{\placeholder{DECAY_COPY}} being evaluated in the constructing thread. Any return value from this invocation is ignored. \begin{note} This implies that any exceptions not thrown from the invocation of the copy of \tcode{f} will be thrown in the constructing thread, not the new thread. \end{note} If the invocation of -\tcode{\textit{INVOKE}(\textit{DECAY_COPY}(} -\tcode{std::forward(f)), \textit{DECAY_COPY}(std::forward(args))...)} -terminates with an uncaught exception, \tcode{terminate} shall be called. +\tcode{% +\placeholdernc{INVOKE}(\brk{}% +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(f)), +\placeholdernc{DECAY_COPY}(\brk{}% +std::forward(args))...)} +termi\-nates with an uncaught exception, \tcode{terminate} shall be called. \pnum\sync The completion of the invocation of the constructor @@ -823,11 +837,12 @@ struct try_to_lock_t { explicit try_to_lock_t() = default; }; struct adopt_lock_t { explicit adopt_lock_t() = default; }; - constexpr defer_lock_t defer_lock { }; - constexpr try_to_lock_t try_to_lock { }; - constexpr adopt_lock_t adopt_lock { }; + inline constexpr defer_lock_t defer_lock { }; + inline constexpr try_to_lock_t try_to_lock { }; + inline constexpr adopt_lock_t adopt_lock { }; - template class lock_guard; + template class lock_guard; + template class scoped_lock; template class unique_lock; template @@ -1559,10 +1574,10 @@ public: shared_timed_mutex(); ~shared_timed_mutex(); - + shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; - + // Exclusive ownership void lock(); // blocking bool try_lock(); @@ -1571,7 +1586,7 @@ template bool try_lock_until(const chrono::time_point& abs_time); void unlock(); - + // Shared ownership void lock_shared(); // blocking bool try_lock_shared(); @@ -1632,9 +1647,9 @@ struct adopt_lock_t { }; // assume the calling thread has already // obtained mutex ownership and manage it - constexpr defer_lock_t defer_lock { }; - constexpr try_to_lock_t try_to_lock { }; - constexpr adopt_lock_t adopt_lock { }; + inline constexpr defer_lock_t defer_lock { }; + inline constexpr try_to_lock_t try_to_lock { }; + inline constexpr adopt_lock_t adopt_lock { }; } \end{codeblock} @@ -1643,40 +1658,121 @@ \indexlibrary{\idxcode{lock_guard}}% \begin{codeblock} namespace std { - template + template class lock_guard { public: - using mutex_type = Mutex; // If \tcode{MutexTypes...} consists of the single type \tcode{Mutex} + using mutex_type = Mutex; - explicit lock_guard(MutexTypes&... m); - lock_guard(MutexTypes&... m, adopt_lock_t); + explicit lock_guard(mutex_type& m); + lock_guard(mutex_type& m, adopt_lock_t); ~lock_guard(); lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; + private: + mutex_type& pm; // \expos + }; + + template lock_guard(lock_guard) -> lock_guard; +} +\end{codeblock} + +\pnum +An object of type \tcode{lock_guard} controls the ownership of a lockable object +within a scope. A \tcode{lock_guard} object maintains ownership of a lockable +object throughout the \tcode{lock_guard} object's lifetime~(\ref{basic.life}). +The behavior of a program is undefined if the lockable object referenced by +\tcode{pm} does not exist for the entire lifetime of the \tcode{lock_guard} +object. The supplied \tcode{Mutex} type shall meet the \tcode{BasicLockable} +requirements~(\ref{thread.req.lockable.basic}). + +\indexlibrary{\idxcode{lock_guard}!constructor}% +\begin{itemdecl} +explicit lock_guard(mutex_type& m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires If \tcode{mutex_type} is not a recursive mutex, +the calling thread does not own the mutex \tcode{m}. + +\pnum +\effects As if by \tcode{m.lock()}. + +\pnum +\postconditions \tcode{\&pm == \&m} +\end{itemdescr} + +\indexlibrary{\idxcode{lock_guard}!constructor}% +\begin{itemdecl} +lock_guard(mutex_type& m, adopt_lock_t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The calling thread owns the mutex \tcode{m}. + +\pnum +\postconditions \tcode{\&pm == \&m} + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrary{\idxcode{lock_guard}!destructor}% +\begin{itemdecl} +~lock_guard(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by \tcode{pm.unlock()}. +\end{itemdescr} + + +\rSec3[thread.lock.scoped]{Class template \tcode{scoped_lock}} + +\indexlibrary{\idxcode{scoped_lock}}% +\begin{codeblock} +namespace std { + template + class scoped_lock { + public: + using mutex_type = Mutex; // If \tcode{MutexTypes...} consists of the single type \tcode{Mutex} + + explicit scoped_lock(MutexTypes&... m); + explicit scoped_lock(MutexTypes&... m, adopt_lock_t); + ~scoped_lock(); + + scoped_lock(const scoped_lock&) = delete; + scoped_lock& operator=(const scoped_lock&) = delete; + private: tuple pm; // \expos }; + + template + scoped_lock(scoped_lock) -> scoped_lock; } \end{codeblock} \pnum -An object of type \tcode{lock_guard} controls the ownership of lockable objects -within a scope. A \tcode{lock_guard} object maintains ownership of lockable -objects throughout the \tcode{lock_guard} object's lifetime~(\ref{basic.life}). +An object of type \tcode{scoped_lock} controls the ownership of lockable objects +within a scope. A \tcode{scoped_lock} object maintains ownership of lockable +objects throughout the \tcode{scoped_lock} object's lifetime~(\ref{basic.life}). The behavior of a program is undefined if the lockable objects referenced by -\tcode{pm} do not exist for the entire lifetime of the \tcode{lock_guard} +\tcode{pm} do not exist for the entire lifetime of the \tcode{scoped_lock} object. When \tcode{sizeof...(MutexTypes)} is \tcode{1}, the supplied \tcode{Mutex} type -shall meet the \tcode{BasicLockable} requirements. +shall meet the \tcode{BasicLockable} requirements~(\ref{thread.req.lockable.basic}). Otherwise, each of the mutex types -shall meet the \tcode{Lockable} requirements~(\ref{thread.req.lockable.basic}). +shall meet the \tcode{Lockable} requirements~(\ref{thread.req.lockable.req}). -\indexlibrary{\idxcode{lock_guard}!constructor}% +\indexlibrary{\idxcode{scoped_lock}!constructor}% \begin{itemdecl} -explicit lock_guard(MutexTypes&... m); +explicit scoped_lock(MutexTypes&... m); \end{itemdecl} \begin{itemdescr} @@ -1688,12 +1784,12 @@ \effects Initializes \tcode{pm} with \tcode{tie(m...)}. Then if \tcode{sizeof...(MutexTypes)} is \tcode{0}, no effects. Otherwise if \tcode{sizeof...(MutexTypes)} is \tcode{1}, then \tcode{m.lock()}. -Otherwise, then \tcode{lock(m...)}. +Otherwise, \tcode{lock(m...)}. \end{itemdescr} -\indexlibrary{\idxcode{lock_guard}!constructor}% +\indexlibrary{\idxcode{scoped_lock}!constructor}% \begin{itemdecl} -lock_guard(MutexTypes&... m, adopt_lock_t); +explicit scoped_lock(MutexTypes&... m, adopt_lock_t); \end{itemdecl} \begin{itemdescr} @@ -1707,14 +1803,14 @@ \throws Nothing. \end{itemdescr} -\indexlibrary{\idxcode{lock_guard}!destructor}% +\indexlibrary{\idxcode{scoped_lock}!destructor}% \begin{itemdecl} -~lock_guard(); +~scoped_lock(); \end{itemdecl} \begin{itemdescr} \pnum -\effects For all \tcode{i} in \tcode{[0, sizeof...(MutexTypes))}, +\effects For all \tcode{i} in \range{0}{sizeof...(MutexTypes)}, \tcode{get(pm).unlock()}. \end{itemdescr} @@ -1771,6 +1867,8 @@ bool owns; // \expos }; + template unique_lock(unique_lock) -> unique_lock; + template void swap(unique_lock& x, unique_lock& y) noexcept; } @@ -2038,7 +2136,7 @@ \pnum \throws Any exception thrown by \tcode{pm->try_lock_until()}. \tcode{system_error} when an -exception is required~(\ref{thread.req.exception}). +exception is required~(\ref{thread.req.exception}). \pnum \errors @@ -2214,6 +2312,8 @@ bool owns; // \expos }; + template shared_lock(shared_lock) -> shared_lock; + template void swap(shared_lock& x, shared_lock& y) noexcept; } @@ -2694,17 +2794,17 @@ \begin{itemdescr} \pnum \requires -\tcode{\textit{INVOKE}(\brk{}} -\tcode{std::forward(func), -std::forward(args)...)} \brk{}(\ref{func.require}) shall be -a valid expression. +\begin{codeblock} +@\placeholdernc{INVOKE}@(std::forward(func), std::forward(args)...) +\end{codeblock} +(see \ref{func.require}) shall be a valid expression. \pnum \effects An execution of \tcode{call_once} that does not call its \tcode{func} is a \term{passive} execution. An execution of \tcode{call_once} that calls its \tcode{func} is an \term{active} execution. An active execution shall call -\tcode{\textit{INVOKE}(} -\tcode{std::forward(func), +\tcode{\placeholdernc{INVOKE}(\brk{}% +std::forward(func), std::forward(args)...)}. If such a call to \tcode{func} throws an exception the execution is \term{exceptional}, otherwise it is \term{returning}. An exceptional execution shall propagate the exception to the caller of @@ -3583,10 +3683,10 @@ struct uses_allocator, Alloc>; template - future(decay_t...)>> + future, decay_t...>> async(F&& f, Args&&... args); template - future(decay_t...)>> + future, decay_t...>> async(launch policy, F&& f, Args&&... args); } \end{codeblock} @@ -3771,7 +3871,7 @@ \pnum A shared state is \defn{ready} only if it holds a value or an exception ready for retrieval. -Waiting for a shared state to become ready may invoke code to compute the result on +Waiting for a shared state to become ready may invoke code to compute the result on the waiting thread if so specified in the description of the class or function that creates the state object. @@ -4044,7 +4144,7 @@ \pnum \errors -\begin{itemize} +\begin{itemize} \item \tcode{promise_already_satisfied} if its shared state already has a stored value or exception. \item \tcode{no_state} if \tcode{*this} has no shared state. @@ -4071,7 +4171,7 @@ \pnum \errors -\begin{itemize} +\begin{itemize} \item \tcode{promise_already_satisfied} if its shared state already has a stored value or exception. \item \tcode{no_state} if \tcode{*this} has no shared state. @@ -4700,9 +4800,11 @@ \indexlibrary{\idxcode{async}}% \begin{itemdecl} template - future(decay_t...)>> async(F&& f, Args&&... args); + future, decay_t...>> + async(F&& f, Args&&... args); template - future(decay_t...)>> async(launch policy, F&& f, Args&&... args); + future, decay_t...>> + async(launch policy, F&& f, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4711,8 +4813,8 @@ satisfy the \tcode{MoveConstructible} requirements, and \begin{codeblock} -@\placeholder{INVOKE}@(@\placeholder{DECAY_COPY}@(std::forward(f)), - @\itcorr[1]\placeholder{DECAY_COPY}@(std::forward(args))...) // see \ref{func.require}, \ref{thread.thread.constr} +@\placeholdernc{INVOKE}@(@\placeholdernc{DECAY_COPY}@(std::forward(f)), + @\placeholdernc{DECAY_COPY}@(std::forward(args))...) // see \ref{func.require}, \ref{thread.thread.constr} \end{codeblock} shall be a valid expression. @@ -4732,17 +4834,17 @@ \begin{itemize} \item If \tcode{launch::async} is set in \tcode{policy}, calls -\tcode{\textit{INVOKE}(\textit{DECAY_COPY}(std::forward(f)),} -\tcode{\textit{DECAY_COPY}(std::forward(args))...)} +\tcode{\placeholdernc{INVOKE}(\placeholdernc{DECAY_COPY}(std::forward(f)),} +\tcode{\placeholdernc{DECAY_COPY}(std::forward(args))...)} (\ref{func.require}, \ref{thread.thread.constr}) as if in a new thread of execution represented by a \tcode{thread} object -with the calls to \tcode{\textit{DECAY_COPY}()} being evaluated in the thread that called \tcode{async}. +with the calls to \tcode{\placeholdernc{DECAY_COPY}()} being evaluated in the thread that called \tcode{async}. Any return value is stored as the result in the shared state. Any exception propagated from the execution of -\tcode{\textit{INVOKE}(\textit{DECAY_COPY}(std::forward(f)), -\textit{DECAY_COPY}(std::forward(args))...)} +\tcode{\placeholdernc{INVOKE}(\placeholdernc{DECAY_COPY}(std::forward(f)), +\placeholdernc{DECAY_COPY}(std::forward(args))...)} is stored as the exceptional result in the shared state. The \tcode{thread} object is stored in the shared state @@ -4751,13 +4853,13 @@ \item If \tcode{launch::deferred} is set in \tcode{policy}, -stores \tcode{\textit{DECAY_COPY}(std::forward(f))} and -\tcode{\textit{DECAY_COPY}(std::forward(args))...} +stores \tcode{\placeholdernc{DECAY_COPY}(std::forward(f))} and +\tcode{\placeholdernc{DECAY_COPY}(std::forward(args))...} in the shared state. These copies of \tcode{f} and \tcode{args} constitute a \defn{deferred function}. Invocation of the deferred function evaluates -\tcode{\textit{INVOKE}(std::move(g), std::move(xyz))} where \tcode{g} is the stored value of -\tcode{\textit{DECAY_COPY}(std::forward(f))} and \tcode{xyz} is the stored copy of -\tcode{\textit{DECAY_COPY}(std::forward(args))...}. +\tcode{\placeholdernc{INVOKE}(std::move(g), std::move(xyz))} where \tcode{g} is the stored value of +\tcode{\placeholdernc{DECAY_COPY}(std::forward(f))} and \tcode{xyz} is the stored copy of +\tcode{\placeholdernc{DECAY_COPY}(std::forward(args))...}. Any return value is stored as the result in the shared state. Any exception propagated @@ -4771,7 +4873,7 @@ on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. -Once evaluation of \tcode{\textit{INVOKE}(std::move(g), std::move(xyz))} begins, the function is no longer +Once evaluation of \tcode{\placeholdernc{INVOKE}(std::move(g), std::move(xyz))} begins, the function is no longer considered deferred. \begin{note} If this policy is specified together with other policies, such as when using a \tcode{policy} value of \tcode{launch::async | launch::deferred}, implementations should defer @@ -4785,7 +4887,7 @@ \pnum \returns An object of type -\tcode{future(decay_t...)>{>}} that refers +\tcode{future, decay_t...>{>}} that refers to the shared state created by this call to \tcode{async}. \begin{note} If a future obtained from \tcode{async} is moved outside the local scope, other code that uses the future must be aware that the future's destructor may @@ -4821,7 +4923,7 @@ synchronizes with~(\ref{intro.multithread}) the return from the first function -that successfully detects the ready status of the shared state or +that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first. @@ -4886,8 +4988,6 @@ packaged_task() noexcept; template explicit packaged_task(F&& f); - template - packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy @@ -4902,7 +5002,7 @@ bool valid() const noexcept; // result retrieval - future get_future(); + future get_future(); // execution void operator()(ArgTypes... ); @@ -4933,27 +5033,23 @@ \begin{itemdecl} template packaged_task(F&& f); -template - packaged_task(allocator_arg_t, const Allocator& a, F&& f); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{\textit{INVOKE}(f, t1, t2, ..., tN, R)}, where \tcode{t1, t2, ..., tN} are values +\tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)}, where \tcode{t1, t2, ..., tN} are values of the corresponding types in \tcode{ArgTypes...}, shall be a valid expression. Invoking a copy of \tcode{f} shall behave the same as invoking \tcode{f}. \pnum \remarks -These constructors shall not participate in overload resolution if \tcode{decay_t} +This constructor shall not participate in overload resolution if \tcode{decay_t} is the same type as \tcode{packaged_task}. \pnum \effects Constructs a new \tcode{packaged_task} object with a shared state and -initializes the object's stored task with \tcode{std::forward(f)}. The constructors that -take an \tcode{Allocator} argument use it to allocate memory needed to store the -internal data structures. +initializes the object's stored task with \tcode{std::forward(f)}. \pnum \throws @@ -5064,7 +5160,7 @@ \begin{itemdescr} \pnum -\effects As if by \tcode{\textit{INVOKE}(f, t1, t2, ..., tN, R)}, +\effects As if by \tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)}, where \tcode{f} is the stored task of \tcode{*this} and \tcode{t1, t2, ..., tN} are the values in \tcode{args...}. If the task returns normally, @@ -5094,7 +5190,7 @@ \begin{itemdescr} \pnum -\effects As if by \tcode{\textit{INVOKE}(f, t1, t2, ..., tN, R)}, +\effects As if by \tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)}, where \tcode{f} is the stored task and \tcode{t1, t2, ..., tN} are the values in \tcode{args...}. If the task returns normally, the return value is stored as the asynchronous result in the shared state of diff --git a/source/utilities.tex b/source/utilities.tex index 4df5dabba5..07c7c1073f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -76,7 +76,7 @@ !is_nothrow_move_constructible_v && is_copy_constructible_v, const T&, T&&> move_if_noexcept(T& x) noexcept; - // \ref{utility.as_const}, as_const + // \ref{utility.as_const}, \tcode{as_const} template constexpr add_const_t& as_const(T& t) noexcept; template @@ -165,7 +165,7 @@ struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; - constexpr piecewise_construct_t piecewise_construct{}; + inline constexpr piecewise_construct_t piecewise_construct{}; template class tuple; // defined in \tcode{} (\ref{tuple.syn}) // in-place construction @@ -415,6 +415,10 @@ The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions. +\indextext{signal-safe!\idxcode{forward}}% +\indextext{signal-safe!\idxcode{move}}% +\indextext{signal-safe!\idxcode{move_if_noexcept}}% +All functions specified in this subclause are signal-safe~(\ref{csignal.syn}). \indexlibrary{\idxcode{forward}}% \begin{itemdecl} @@ -905,6 +909,9 @@ void swap(pair& p) noexcept(@\seebelow@); }; + + template + pair(T1, T2) -> pair; } \end{codeblock} @@ -914,10 +921,13 @@ throws an exception. \pnum -The defaulted move and copy constructor, respectively, of pair shall +The defaulted move and copy constructor, respectively, of \tcode{pair} shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function. +The destructor of \tcode{pair} shall be a trivial destructor if +\tcode{(is_trivially_destructible_v \&\& is_trivially_destructible_v)} +is \tcode{true}. \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} @@ -1357,7 +1367,7 @@ struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; -constexpr piecewise_construct_t piecewise_construct{}; +inline constexpr piecewise_construct_t piecewise_construct{}; \end{itemdecl} \pnum @@ -1392,7 +1402,7 @@ class tuple; // \ref{tuple.creation}, tuple creation functions - constexpr @\unspec@ ignore; + inline constexpr @\unspec@ ignore; template constexpr tuple make_tuple(TTypes&&...); @@ -1474,7 +1484,7 @@ // \ref{tuple.helper}, tuple helper classes template - constexpr size_t tuple_size_v = tuple_size::value; + inline constexpr size_t tuple_size_v = tuple_size::value; } \end{codeblock} @@ -1542,6 +1552,17 @@ // \ref{tuple.swap}, \tcode{tuple} swap void swap(tuple&) noexcept(@\seebelow@); }; + + template + tuple(UTypes...) -> tuple; + template + tuple(pair) -> tuple; + template + tuple(allocator_arg_t, Alloc, UTypes...) -> tuple; + template + tuple(allocator_arg_t, Alloc, pair) -> tuple; + template + tuple(allocator_arg_t, Alloc, tuple) -> tuple; } \end{codeblock} @@ -1559,6 +1580,11 @@ defaulted move and copy constructor of \tcode{tuple<>} shall be constexpr functions. +\pnum +The destructor of tuple shall be a trivial destructor if +\tcode{(is_trivially_destructible_v \&\& ...)} +is \tcode{true}. + \pnum In the constructor descriptions that follow, let $i$ be in the range \range{0}{sizeof...(Types)} in order, $\tcode{T}_i$ @@ -2104,7 +2130,7 @@ template constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence) { // exposition only - return @\textit{INVOKE}@(std::forward(f), std::get(std::forward(t))...); + return @\placeholdernc{INVOKE}@(std::forward(f), std::get(std::forward(t))...); } \end{codeblock} Equivalent to: @@ -2318,8 +2344,8 @@ \begin{example} \begin{codeblock} const tuple t(1, 2, 3.4, 5.6); - const int& i1 = get(t); // OK. Not ambiguous. i1 == 1 - const int& i2 = get(t); // OK. Not ambiguous. i2 == 2 + const int& i1 = get(t); // OK. Not ambiguous. \tcode{i1 == 1} + const int& i2 = get(t); // OK. Not ambiguous. \tcode{i2 == 2} const double& d = get(t); // ERROR. ill-formed \end{codeblock} \end{example} @@ -2500,24 +2526,24 @@ // \ref{optional.nullopt}, no-value state indicator struct nullopt_t{@\seebelow@}; - constexpr nullopt_t nullopt(@\unspec@); + inline constexpr nullopt_t nullopt(@\unspec@); // \ref{optional.bad.access}, class \tcode{bad_optional_access} class bad_optional_access; // \ref{optional.relops}, relational operators - template - constexpr bool operator==(const optional&, const optional&); - template - constexpr bool operator!=(const optional&, const optional&); - template - constexpr bool operator<(const optional&, const optional&); - template - constexpr bool operator>(const optional&, const optional&); - template - constexpr bool operator<=(const optional&, const optional&); - template - constexpr bool operator>=(const optional&, const optional&); + template + constexpr bool operator==(const optional&, const optional&); + template + constexpr bool operator!=(const optional&, const optional&); + template + constexpr bool operator<(const optional&, const optional&); + template + constexpr bool operator>(const optional&, const optional&); + template + constexpr bool operator<=(const optional&, const optional&); + template + constexpr bool operator>=(const optional&, const optional&); // \ref{optional.nullops}, comparison with \tcode{nullopt} template constexpr bool operator==(const optional&, nullopt_t) noexcept; @@ -2534,18 +2560,18 @@ 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 T&); - template constexpr bool operator==(const T&, const optional&); - template constexpr bool operator!=(const optional&, const T&); - template constexpr bool operator!=(const T&, const optional&); - template constexpr bool operator<(const optional&, const T&); - template constexpr bool operator<(const T&, const optional&); - template constexpr bool operator<=(const optional&, const T&); - template constexpr bool operator<=(const T&, const optional&); - template constexpr bool operator>(const optional&, const T&); - template constexpr bool operator>(const T&, const optional&); - template constexpr bool operator>=(const optional&, const T&); - template constexpr bool operator>=(const T&, 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 U&, const optional&); // \ref{optional.specalg}, specialized algorithms template @@ -2581,8 +2607,8 @@ // \ref{optional.ctor}, constructors constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; - optional(const optional&); - optional(optional&&) noexcept(@\seebelow@); + constexpr optional(const optional&); + constexpr optional(optional&&) noexcept(@\seebelow@); template constexpr explicit optional(in_place_t, Args&&...); template @@ -2604,8 +2630,8 @@ template optional& operator=(U&&); template optional& operator=(const optional&); template optional& operator=(optional&&); - template void emplace(Args&&...); - template void emplace(initializer_list, Args&&...); + template T& emplace(Args&&...); + template T& emplace(initializer_list, Args&&...); // \ref{optional.swap}, swap void swap(optional&) noexcept(@\seebelow@); @@ -2632,6 +2658,8 @@ private: T *val; // \expos }; + +template optional(T) -> optional; \end{codeblock} \pnum @@ -2672,7 +2700,7 @@ \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -optional(const optional& rhs); +constexpr optional(const optional& rhs); \end{itemdecl} \begin{itemdescr} @@ -2693,11 +2721,13 @@ \remarks This constructor shall be defined as deleted unless \tcode{is_copy_constructible_v} is \tcode{true}. +If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, +this constructor shall be a \tcode{constexpr} constructor. \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -optional(optional&& rhs) noexcept(@\seebelow@); +constexpr optional(optional&& rhs) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -2721,6 +2751,8 @@ \tcode{is_nothrow_move_constructible_v}. This constructor shall not participate in overload resolution unless \tcode{is_move_constructible_v} is \tcode{true}. +If \tcode{is_trivially_move_constructible_v} is \tcode{true}, +this constructor shall be a \tcode{constexpr} constructor. \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% @@ -2743,7 +2775,7 @@ \pnum \remarks -If \tcode{T}'s constructor selected for the initialization is a constexpr constructor, this constructor shall be a \tcode{constexpr} constructor. +If \tcode{T}'s constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor. This constructor shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} @@ -2770,7 +2802,7 @@ \pnum \remarks This constructor shall not participate in overload resolution unless \tcode{is_constructible_v\&, Args\&\&...>} is \tcode{true}. -If \tcode{T}'s constructor selected for the initialization is a constexpr constructor, this constructor shall be a \tcode{constexpr} constructor. +If \tcode{T}'s constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor. \end{itemdescr} \pnum @@ -2805,7 +2837,7 @@ 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} is \tcode{false}, and +\tcode{is_same_v, in_place_t>} is \tcode{false}, and \tcode{is_same_v, decay_t>} is \tcode{false}. The constructor is explicit if and only if \tcode{is_convertible_v} is \tcode{false}. @@ -2898,7 +2930,10 @@ \begin{itemdescr} \pnum \effects -If \tcode{is_trivially_destructible_v != true} and \tcode{*this} contains a value, calls \tcode{val->T::\~T()}. +If \tcode{is_trivially_destructible_v != true} and \tcode{*this} contains a value, calls +\begin{codeblock} +val->T::~T() +\end{codeblock} \pnum \remarks @@ -3171,7 +3206,7 @@ \indexlibrarymember{emplace}{optional}% \begin{itemdecl} -template void emplace(Args&&... args); +template T& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -3187,6 +3222,10 @@ \postconditions \tcode{*this} contains a value. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown by the selected constructor of \tcode{T}. @@ -3198,7 +3237,7 @@ \indexlibrarymember{emplace}{optional}% \begin{itemdecl} -template void emplace(initializer_list il, Args&&... args); +template T& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -3210,6 +3249,10 @@ \postconditions \tcode{*this} contains a value. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown by the selected constructor of \tcode{T}. @@ -3459,7 +3502,7 @@ \indexlibrary{\idxcode{nullopt}}% \begin{itemdecl} struct nullopt_t{@\seebelow@}; -constexpr nullopt_t nullopt(@\unspec@); +inline constexpr nullopt_t nullopt(@\unspec@); \end{itemdecl} \pnum @@ -3473,7 +3516,7 @@ \rSec2[optional.bad.access]{Class \tcode{bad_optional_access}} \begin{codeblock} -class bad_optional_access : public logic_error { +class bad_optional_access : public exception { public: bad_optional_access(); }; @@ -3504,7 +3547,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} @@ -3527,7 +3570,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} @@ -3551,7 +3594,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} @@ -3575,7 +3618,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} @@ -3599,7 +3642,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} @@ -3623,7 +3666,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} @@ -3763,10 +3806,18 @@ \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const optional& x, const T& v); +template constexpr bool operator==(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x == v} shall be well-formed and +its result shall be convertible to \tcode{bool}. +\begin{note} +\tcode{T} need not be \tcode{EqualityComparable}. +\end{note} + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x == v :\ false;} @@ -3774,10 +3825,15 @@ \indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const T& v, const optional& x); +template constexpr bool operator==(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v == *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v == *x :\ false;} @@ -3785,10 +3841,15 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const optional& x, const T& v); +template constexpr bool operator!=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x != v} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x != v :\ true;} @@ -3796,10 +3857,15 @@ \indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const T& v, const optional& x); +template constexpr bool operator!=(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v != *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v != *x :\ true;} @@ -3807,10 +3873,15 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const optional& x, const T& v); +template constexpr bool operator<(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x < v} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x < v :\ true;} @@ -3818,10 +3889,15 @@ \indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const T& v, const optional& x); +template constexpr bool operator<(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v < *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v < *x :\ false;} @@ -3829,10 +3905,15 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const optional& x, const T& v); +template constexpr bool operator<=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x <= v} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x <= v :\ true;} @@ -3840,10 +3921,15 @@ \indexlibrarymember{operator<=}{optional}% \begin{itemdecl} -template constexpr bool operator<=(const T& v, const optional& x); +template constexpr bool operator<=(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v <= *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v <= *x :\ false;} @@ -3851,10 +3937,15 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const optional& x, const T& v); +template constexpr bool operator>(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x > v} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x > v :\ false;} @@ -3862,10 +3953,15 @@ \indexlibrarymember{operator>}{optional}% \begin{itemdecl} -template constexpr bool operator>(const T& v, const optional& x); +template constexpr bool operator>(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v > *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v > *x :\ true;} @@ -3873,10 +3969,15 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const optional& x, const T& v); +template constexpr bool operator>=(const optional& x, const U& v); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{*x >= v} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ *x >= v :\ false;} @@ -3884,10 +3985,15 @@ \indexlibrarymember{operator>=}{optional}% \begin{itemdecl} -template constexpr bool operator>=(const T& v, const optional& x); +template constexpr bool operator>=(const U& v, const optional& x); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression \tcode{v >= *x} shall be well-formed and +its result shall be convertible to \tcode{bool}. + \pnum \effects Equivalent to: \tcode{return bool(x) ?\ v >= *x :\ true;} @@ -3960,6 +4066,7 @@ if \tcode{bool(o) == true}, then \tcode{hash>()(o)} shall evaluate to the same value as \tcode{hash>()(*o)}; otherwise it evaluates to an unspecified value. +The member functions are not guaranteed to be \tcode{noexcept}. \end{itemdescr} @@ -3989,7 +4096,7 @@ template struct variant_size; template struct variant_size; template - constexpr size_t variant_size_v = variant_size::value; + inline constexpr size_t variant_size_v = variant_size::value; template struct variant_size>; @@ -4004,7 +4111,7 @@ template struct variant_alternative>; - constexpr size_t variant_npos = -1; + inline constexpr size_t variant_npos = -1; // \ref{variant.get}, value access template @@ -4146,13 +4253,13 @@ // \ref{variant.mod}, modifiers template - void emplace(Args&&...); + T& emplace(Args&&...); template - void emplace(initializer_list, Args&&...); + T& emplace(initializer_list, Args&&...); template - void emplace(Args&&...); + variant_alternative_t>& emplace(Args&&...); template - void emplace(initializer_list, Args&&...); + variant_alternative_t>& emplace(initializer_list, Args&&...); // \ref{variant.status}, value status constexpr bool valueless_by_exception() const noexcept; @@ -4169,7 +4276,7 @@ of one of its alternative types, or it holds no value. When an instance of \tcode{variant} holds a value of alternative type \tcode{T}, it means that a value of type \tcode{T}, referred to as the \tcode{variant} -object's contained value, is allocated within the storage of the +object's \defnx{contained value}{contained value!\idxcode{variant}}, is allocated within the storage of the \tcode{variant} object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. @@ -4332,7 +4439,9 @@ \begin{itemdescr} \pnum \effects -Initializes the contained value of type \tcode{T} with the arguments \tcode{std::forward(args)...}. +Initializes the contained value as if direct-non-list-initializing +an object of type \tcode{T} +with the arguments \tcode{std::forward(args)...}. \pnum \postconditions @@ -4360,7 +4469,8 @@ \begin{itemdescr} \pnum \effects -Initializes the contained value as if constructing an object of type \tcode{T} +Initializes the contained value as if direct-non-list-initializing +an object of type \tcode{T} with the arguments \tcode{il, std::forward(args)...}. \pnum @@ -4388,7 +4498,8 @@ \begin{itemdescr} \pnum \effects -Initializes the contained value as if constructing an object of type $\tcode{T}_I$ +Initializes the contained value as if direct-non-list-initializing +an object of type $\tcode{T}_I$ with the arguments \tcode{std::forward(args)...}. \pnum @@ -4401,8 +4512,13 @@ \pnum \remarks -This function shall not participate in overload resolution unless \tcode{I} is -less than \tcode{sizeof...(Types)} and \tcode{is_constructible_v<$\tcode{T}_I$, Args...>} is \tcode{true}. +This function shall not participate in overload resolution unless +\begin{itemize} +\item +\tcode{I} is less than \tcode{sizeof...(Types)} and +\item +\tcode{is_constructible_v<$\tcode{T}_I$, Args...>} is \tcode{true}. +\end{itemize} If $\tcode{T}_I$'s selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor. \end{itemdescr} @@ -4416,8 +4532,9 @@ \begin{itemdescr} \pnum \effects -Initializes the contained value as if constructing an object of type -$\tcode{T}_I$ with the arguments \tcode{il, std::forward(args)...}. +Initializes the contained value as if direct-non-list-initializing +an object of type $\tcode{T}_I$ +with the arguments \tcode{il, std::forward(args)...}. \pnum \postconditions @@ -4425,9 +4542,13 @@ \pnum \remarks -This function shall not participate in overload resolution unless \tcode{I} is -less than \tcode{sizeof...(Types)} and +This function shall not participate in overload resolution unless +\begin{itemize} +\item +\tcode{I} is less than \tcode{sizeof...(Types)} and +\item \tcode{is_constructible_v<$\tcode{T}_I$, initializer_list\&, Args...>} is \tcode{true}. +\end{itemize} If $\tcode{T}_I$'s selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor. \end{itemdescr} @@ -4493,6 +4614,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let $j$ be \tcode{rhs.index()}. + \pnum \effects \begin{itemize} @@ -4502,15 +4626,14 @@ 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, \item -if \tcode{index() == rhs.index()}, assigns the value contained in \tcode{rhs} +if \tcode{index() == $j$}, assigns the value contained in \tcode{rhs} to the value contained in \tcode{*this}. Otherwise, \item -copies the value contained in \tcode{rhs} to a temporary, then destroys any -value contained in \tcode{*this}. Sets \tcode{*this} to hold the same -alternative index as \tcode{rhs} and initializes the value contained in -\tcode{*this} as if direct-non-list-initializing an object of type $\tcode{T}_j$ -with \tcode{std::forward<$\tcode{T}_j$>(TMP)}, with \tcode{TMP} being the temporary and -$j$ being \tcode{rhs.index()}. +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, +\item +equivalent to \tcode{operator=(variant(rhs))}. \end{itemize} \pnum @@ -4522,17 +4645,9 @@ \pnum \remarks This function shall not participate in overload resolution unless -\tcode{is_copy_constructible_v<$\tcode{T}_i$> \&\& is_move_constructible_v<$\tcode{T}_i$> \&\& is_copy_assignable_v<$\tcode{T}_i$>} +\tcode{is_copy_constructible_v<$\tcode{T}_i$> \&\&} +\tcode{is_copy_assignable_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. -\begin{itemize} -\item If an exception is thrown during the call to $\tcode{T}_j$'s copy assignment, -the state of the contained value is as defined by the exception safety -guarantee of $\tcode{T}_j$'s copy assignment; \tcode{index()} will be $j$. -\item If an exception is thrown during the call to $\tcode{T}_j$'s copy construction -(with $j$ being \tcode{rhs.index()}), \tcode{*this} will remain unchanged. -\item If an exception is thrown during the call to $\tcode{T}_j$'s move construction, -the \tcode{variant} will hold no value. -\end{itemize} \end{itemdescr} \indexlibrarymember{operator=}{variant}% @@ -4541,6 +4656,9 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let $j$ be \tcode{rhs.index()}. + \pnum \effects \begin{itemize} @@ -4550,13 +4668,10 @@ 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, \item -if \tcode{index() == rhs.index()}, assigns \tcode{get<$j$>(std::move(rhs))} to -the value contained in \tcode{*this}, with $j$ being \tcode{index()}. Otherwise, +if \tcode{index() == $j$}, assigns \tcode{get<$j$>(std::move(rhs))} to +the value contained in \tcode{*this}. Otherwise, \item -destroys any value contained in \tcode{*this}. Sets \tcode{*this} to hold the -same alternative index as \tcode{rhs} and initializes the value contained in -\tcode{*this} as if direct-non-list-initializing an object of type $\tcode{T}_j$ -with \tcode{get<$j$>(std::move(rhs))} with $j$ being \tcode{rhs.index()}. +equivalent to \tcode{emplace<$j$>(get<$j$>(std::move(rhs)))}. \end{itemize} \pnum @@ -4594,12 +4709,17 @@ \pnum \effects +\begin{itemize} +\item If \tcode{*this} holds a $\tcode{T}_j$, assigns \tcode{std::forward(t)} to -the value contained in \tcode{*this}. Otherwise, destroys any value contained -in \tcode{*this}, sets \tcode{*this} to hold the alternative type $\tcode{T}_j$ -as selected by the imaginary function overload resolution described above, -and direct-initializes the contained value as if direct-non-list-initializing -it with \tcode{std::forward(t)}. +the value contained in \tcode{*this}. Otherwise, +\item +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, +\item +equivalent to \tcode{operator=(variant(std::forward(t)))}. +\end{itemize} \pnum \postconditions @@ -4646,14 +4766,16 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template void emplace(Args&&... args); +template T& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} +\pnum +Let $I$ be the zero-based index of \tcode{T} in \tcode{Types...}. + \pnum \effects -Equivalent to \tcode{emplace<$I$>(std::forward(args)...)} where $I$ -is the zero-based index of \tcode{T} in \tcode{Types...}. +Equivalent to: \tcode{return emplace<$I$>(std::forward(args)...);} \pnum \remarks @@ -4664,14 +4786,16 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template void emplace(initializer_list il, Args&&... args); +template T& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} +\pnum +Let $I$ be the zero-based index of \tcode{T} in \tcode{Types...}. + \pnum \effects -Equivalent to \tcode{emplace<$I$>(il, std::forward(args)...)} where -$I$ is the zero-based index of \tcode{T} in \tcode{Types...}. +Equivalent to: \tcode{return emplace<$I$>(il, std::forward(args)...);} \pnum \remarks @@ -4682,7 +4806,8 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template void emplace(Args&&... args); +template + variant_alternative_t>& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4693,14 +4818,19 @@ \pnum \effects Destroys the currently contained value if \tcode{valueless_by_exception()} -is \tcode{false}. Then direct-initializes the contained value as if -constructing a value of type $\tcode{T}_I$ with the arguments -\tcode{std::forward(args)...}. +is \tcode{false}. +Then initializes the contained value as if direct-non-list-initializing +a value of type $\tcode{T}_I$ +with the arguments \tcode{std::forward(args)...}. \pnum \postconditions \tcode{index()} is \tcode{I}. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown during the initialization of the contained value. @@ -4715,7 +4845,8 @@ \indexlibrarymember{emplace}{variant}% \begin{itemdecl} -template void emplace(initializer_list il, Args&&... args); +template + variant_alternative_t>& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -4726,14 +4857,19 @@ \pnum \effects Destroys the currently contained value if \tcode{valueless_by_exception()} -is \tcode{false}. Then direct-initializes the contained value as if -constructing a value of type $\tcode{T}_I$ with the arguments -\tcode{il, std::forward(args)...}. +is \tcode{false}. +Then initializes the contained value as if direct-non-list-initializing +a value of type $\tcode{T}_I$ +with the arguments \tcode{il, std::forward(args)...}. \pnum \postconditions \tcode{index()} is \tcode{I}. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown during the initialization of the contained value. @@ -5151,12 +5287,12 @@ \pnum \effects -Let \tcode{is...} be \tcode{vars.index()...}. Returns \tcode{\textit{INVOKE}(forward(vis), get(}\brk{} +Let \tcode{is...} be \tcode{vars.index()...}. Returns \tcode{\placeholdernc{INVOKE}(forward(vis), get(}\brk{} \tcode{forward(vars))...);}. \pnum \remarks -The return type is the common type of all possible \tcode{\textit{INVOKE}} +The return type is the common type of all possible \tcode{\placeholder{INVOKE}} expressions of the \effects element. \pnum @@ -5273,6 +5409,7 @@ \pnum The specialization \tcode{hash>} is enabled~(\ref{unord.hash}) if and only if every specialization in \tcode{hash>...} is enabled. +The member functions are not guaranteed to be \tcode{noexcept}. \end{itemdescr} \indexlibrary{\idxcode{hash}!\idxcode{monostate}}% @@ -5367,6 +5504,21 @@ \pnum Objects of type \tcode{bad_any_cast} are thrown by a failed \tcode{any_cast}~(\ref{any.nonmembers}). +\indexlibrarymember{what}{bad_any_access}% +\begin{itemdecl} +const char* what() const noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns An \impldef{return value of \tcode{bad_any_access::what}} \ntbs. + +\pnum +\remarks +The message may be a null-terminated multibyte string~(\ref{multibyte.strings}), +suitable for conversion and display as a wstring~(\ref{string.classes}, \ref{locale.codecvt}). +\end{itemdescr} + \rSec2[any.class]{Class \tcode{any}} \begin{codeblock} @@ -5395,9 +5547,9 @@ // \ref{any.modifiers}, modifiers template - void emplace(Args&& ...); + decay_t& emplace(Args&& ...); template - void emplace(initializer_list, Args&&...); + decay_t& emplace(initializer_list, Args&&...); void reset() noexcept; void swap(any& rhs) noexcept; @@ -5410,14 +5562,14 @@ \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 \defn{contained object}. -Two states are equivalent if either they both have no value, or both have a value and the contained objects are equivalent. +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 -The non-member \tcode{any_cast} functions provide type-safe access to the contained object. +The non-member \tcode{any_cast} functions provide type-safe access to the contained value. \pnum -Implementations should avoid the use of dynamically allocated memory for a small contained object. +Implementations should avoid the use of dynamically allocated memory for a small contained value. \begin{example} where the object constructed is holding only an \tcode{int}. \end{example} @@ -5445,11 +5597,13 @@ \begin{itemdescr} \pnum \effects -Constructs an object of type \tcode{any} with an equivalent state as \tcode{other}. +If \tcode{other.has_value()} is \tcode{false}, constructs an object that has no value. +Otherwise, equivalent to \tcode{any(in_place, any_cast(other))} +where \tcode{T} is the type of the contained object. \pnum \throws -Any exceptions arising from calling the selected constructor of the contained object. +Any exceptions arising from calling the selected constructor for the contained value. \end{itemdescr} \indexlibrary{\idxcode{any}!constructor}% @@ -5460,7 +5614,11 @@ \begin{itemdescr} \pnum \effects -Constructs an object of type \tcode{any} with a state equivalent to the original state of \tcode{other}. +If \tcode{other.has_value()} is \tcode{false}, constructs an object that has no value. +Otherwise, constructs an object of type \tcode{any} that +contains either the contained object of \tcode{other}, or +contains an object of the same type constructed from +the contained object of \tcode{other} considering that contained object as an rvalue. \pnum \postconditions @@ -5587,7 +5745,7 @@ \pnum \throws -Any exceptions arising from the copy constructor of the contained object. +Any exceptions arising from the copy constructor for the contained value. \end{itemdescr} \indexlibrarymember{operator=}{any}% @@ -5636,12 +5794,12 @@ \pnum \remarks This operator shall not participate in overload resolution unless -\tcode{T} is not the same type as \tcode{any} and -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{VT} is not the same type as \tcode{any} and +\tcode{is_copy_constructible_v} is \tcode{true}. \pnum \throws -Any exception thrown by the selected constructor of \tcode{T}. +Any exception thrown by the selected constructor of \tcode{VT}. \end{itemdescr} \rSec3[any.modifiers]{Modifiers} @@ -5649,7 +5807,7 @@ \indexlibrarymember{emplace}{any}% \begin{itemdecl} template - void emplace(Args&&... args); + decay_t& emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -5668,12 +5826,16 @@ \pnum \postconditions \tcode{*this} contains a value. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown by the selected constructor of \tcode{VT}. \pnum \remarks If an exception is thrown during the call to \tcode{VT}'s constructor, -\tcode{*this} does not contain a value, and any previously contained object +\tcode{*this} does not contain a value, and any previously contained value has been destroyed. This function shall not participate in overload resolution unless \tcode{is_copy_constructible_v} is \tcode{true} and @@ -5683,7 +5845,7 @@ \indexlibrarymember{emplace}{any}% \begin{itemdecl} template - void emplace(initializer_list il, Args&&... args); + decay_t& emplace(initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -5702,12 +5864,16 @@ \pnum \postconditions \tcode{*this} contains a value. +\pnum +\returns +A reference to the new contained value. + \pnum \throws Any exception thrown by the selected constructor of \tcode{VT}. \pnum \remarks If an exception is thrown during the call to \tcode{VT}'s constructor, -\tcode{*this} does not contain a value, and any previously contained object +\tcode{*this} does not contain a value, and any previously contained value has been destroyed. The function shall not participate in overload resolution unless \tcode{is_copy_constructible_v} is \tcode{true} and @@ -5722,7 +5888,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{has_value()} is \tcode{true}, destroys the contained object. +If \tcode{has_value()} is \tcode{true}, destroys the contained value. \pnum \postconditions @@ -5762,7 +5928,7 @@ \begin{itemdescr} \pnum \returns -\tcode{typeid(T)} if \tcode{*this} has a contained object of type \tcode{T}, +\tcode{typeid(T)} if \tcode{*this} has a contained value of type \tcode{T}, otherwise \tcode{typeid(void)}. \pnum @@ -5819,15 +5985,20 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{U} be the type \tcode{remove_cv_t>}. + \pnum \requires -\tcode{is_reference_v} is \tcode{true} or \tcode{is_copy_constructible_v} is \tcode{true}. +For the first overload, \tcode{is_constructible_v} is \tcode{true}. +For the second overload, \tcode{is_constructible_v} is \tcode{true}. +For the third overload, \tcode{is_constructible_v} is \tcode{true}. Otherwise the program is ill-formed. \pnum \returns -For the first form, \tcode{*any_cast>>(\&operand)}. -For the second and third forms, \tcode{*any_cast>(\&operand)}. +For the first and second overload, \tcode{static_cast(*any_cast(\&operand))}. +For the third overload, \tcode{static_cast(std::move(*any_cast(\&operand)))}. \pnum \throws @@ -5938,7 +6109,7 @@ friend class bitset; reference() noexcept; public: - ~reference() noexcept; + ~reference() noexcept; reference& operator=(bool x) noexcept; // for \tcode{b[i] = x;} reference& operator=(const reference&) noexcept; // for \tcode{b[i] = b[j];} bool operator~() const noexcept; // flips the bit @@ -6797,7 +6968,7 @@ // \ref{allocator.tag}, allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; - constexpr allocator_arg_t allocator_arg{}; + inline constexpr allocator_arg_t allocator_arg{}; // \ref{allocator.uses}, \tcode{uses_allocator} template struct uses_allocator; @@ -6888,7 +7059,7 @@ ForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n); - // \ref{unique.ptr}, class template unique_ptr + // \ref{unique.ptr}, class template \tcode{unique_ptr} template struct default_delete; template struct default_delete; template > class unique_ptr; @@ -6938,19 +7109,19 @@ template bool operator>=(nullptr_t, const unique_ptr& y); - // \ref{util.smartptr.weak.bad}, class bad_weak_ptr + // \ref{util.smartptr.weak.bad}, class \tcode{bad_weak_ptr} class bad_weak_ptr; - // \ref{util.smartptr.shared}, class template shared_ptr + // \ref{util.smartptr.shared}, class template \tcode{shared_ptr} template class shared_ptr; - // \ref{util.smartptr.shared.create}, shared_ptr creation + // \ref{util.smartptr.shared.create}, \tcode{shared_ptr} creation template shared_ptr make_shared(Args&&... args); template shared_ptr allocate_shared(const A& a, Args&&... args); - // \ref{util.smartptr.shared.cmp}, shared_ptr comparisons + // \ref{util.smartptr.shared.cmp}, \tcode{shared_ptr} comparisons template bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; template @@ -6989,11 +7160,11 @@ template bool operator>=(nullptr_t, const shared_ptr& y) noexcept; - // \ref{util.smartptr.shared.spec}, shared_ptr specialized algorithms + // \ref{util.smartptr.shared.spec}, \tcode{shared_ptr} specialized algorithms template void swap(shared_ptr& a, shared_ptr& b) noexcept; - // \ref{util.smartptr.shared.cast}, shared_ptr casts + // \ref{util.smartptr.shared.cast}, \tcode{shared_ptr} casts template shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; template @@ -7001,27 +7172,27 @@ template shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; - // \ref{util.smartptr.getdeleter}, shared_ptr get_deleter + // \ref{util.smartptr.getdeleter}, \tcode{shared_ptr} \tcode{get_deleter} template D* get_deleter(const shared_ptr& p) noexcept; - // \ref{util.smartptr.shared.io}, shared_ptr I/O + // \ref{util.smartptr.shared.io}, \tcode{shared_ptr} I/O template basic_ostream& operator<< (basic_ostream& os, const shared_ptr& p); - // \ref{util.smartptr.weak}, class template weak_ptr + // \ref{util.smartptr.weak}, class template \tcode{weak_ptr} template class weak_ptr; - // \ref{util.smartptr.weak.spec}, weak_ptr specialized algorithms + // \ref{util.smartptr.weak.spec}, \tcode{weak_ptr} specialized algorithms template void swap(weak_ptr& a, weak_ptr& b) noexcept; - // \ref{util.smartptr.ownerless}, class template owner_less + // \ref{util.smartptr.ownerless}, class template \tcode{owner_less} template struct owner_less; - // \ref{util.smartptr.enab}, class template enable_shared_from_this + // \ref{util.smartptr.enab}, class template \tcode{enable_shared_from_this} template class enable_shared_from_this; - // \ref{util.smartptr.shared.atomic}, shared_ptr atomic access + // \ref{util.smartptr.shared.atomic}, \tcode{shared_ptr} atomic access template bool atomic_is_lock_free(const shared_ptr* p); @@ -7060,9 +7231,9 @@ template struct hash>; template struct hash>; - // \ref{allocator.uses.trait}, uses_allocator + // \ref{allocator.uses.trait}, \tcode{uses_allocator} template - constexpr bool uses_allocator_v = uses_allocator::value; + inline constexpr bool uses_allocator_v = uses_allocator::value; } \end{codeblock} @@ -7331,7 +7502,7 @@ \begin{itemdecl} namespace std { struct allocator_arg_t { explicit allocator_arg_t() = default; }; - constexpr allocator_arg_t allocator_arg{}; + inline constexpr allocator_arg_t allocator_arg{}; } \end{itemdecl} @@ -7375,7 +7546,7 @@ \rSec3[allocator.uses.construction]{Uses-allocator construction} \pnum -\defn{Uses-allocator construction} with allocator \tcode{Alloc} refers to the +\defnx{Uses-allocator construction}{uses-allocator construction} with allocator \tcode{Alloc} refers to the construction of an object \tcode{obj} of type \tcode{T}, using constructor arguments \tcode{v1, v2, ..., vN} of types \tcode{V1, V2, ..., VN}, respectively, and an allocator \tcode{alloc} of type \tcode{Alloc}, according to the following rules: @@ -7683,7 +7854,7 @@ \pnum All specializations of the default allocator satisfy the -allocator completeness requirements~\ref{allocator.requirements.completeness}. +allocator completeness requirements~(\ref{allocator.requirements.completeness}). \indexlibrary{\idxcode{allocator}}% \begin{codeblock} @@ -7697,7 +7868,7 @@ allocator() noexcept; allocator(const allocator&) noexcept; template allocator(const allocator&) noexcept; - ~allocator(); + ~allocator(); T* allocate(size_t n); void deallocate(T* p, size_t n); @@ -8351,7 +8522,7 @@ Calls \tcode{delete[]} on \tcode{ptr}. \pnum -\remarks If U is an incomplete type, the program is ill-formed. +\remarks If \tcode{U} is an incomplete type, the program is ill-formed. This function shall not participate in overload resolution unless \tcode{U(*)[]} is convertible to \tcode{T(*)[]}. \end{itemdescr} @@ -8373,8 +8544,7 @@ unique_ptr(pointer p, @\seebelow@ d1) noexcept; unique_ptr(pointer p, @\seebelow@ d2) noexcept; unique_ptr(unique_ptr&& u) noexcept; - constexpr unique_ptr(nullptr_t) noexcept - : unique_ptr() { } + constexpr unique_ptr(nullptr_t) noexcept; template unique_ptr(unique_ptr&& u) noexcept; @@ -8441,6 +8611,7 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} constexpr unique_ptr() noexcept; +constexpr unique_ptr(nullptr_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8458,8 +8629,9 @@ returns a reference to the stored deleter. \pnum -\remarks If this constructor is instantiated with a pointer type or reference type -for the template argument \tcode{D}, the program is ill-formed. +\remarks If \tcode{is_pointer_v} is \tcode{true} or +\tcode{is_default_constructible_v} is \tcode{false}, +this constructor shall not participate in overload resolution. \end{itemdescr} \indexlibrary{\idxcode{unique_ptr}!constructor}% @@ -8483,8 +8655,12 @@ returns a reference to the stored deleter. \pnum -\remarks If this constructor is instantiated with a pointer type or reference type -for the template argument \tcode{D}, the program is ill-formed. +\remarks If \tcode{is_pointer_v} is \tcode{true} or +\tcode{is_default_constructible_v} is \tcode{false}, +this constructor shall not participate in overload resolution. +If class template argument deduction~(\ref{over.match.class.deduct}) +would select the function template corresponding to this constructor, +then the program is ill-formed. \end{itemdescr} \indexlibrary{\idxcode{unique_ptr}!constructor}% @@ -8500,8 +8676,8 @@ \tcode{A}, then the signatures are: \begin{codeblock} -unique_ptr(pointer p, const A& d); -unique_ptr(pointer p, A&& d); +unique_ptr(pointer p, const A& d) noexcept; +unique_ptr(pointer p, A&& d) noexcept; \end{codeblock} \pnum @@ -8509,8 +8685,8 @@ then the signatures are: \begin{codeblock} -unique_ptr(pointer p, A& d); -unique_ptr(pointer p, A&& d); +unique_ptr(pointer p, A& d) noexcept; +unique_ptr(pointer p, A&& d) = delete; \end{codeblock} \pnum @@ -8518,51 +8694,18 @@ then the signatures are: \begin{codeblock} -unique_ptr(pointer p, const A& d); -unique_ptr(pointer p, const A&& d); +unique_ptr(pointer p, const A& d) noexcept; +unique_ptr(pointer p, const A&& d) = delete; \end{codeblock} \pnum -\requires -\begin{itemize} -\item If \tcode{D} is not an lvalue reference type then - -\begin{itemize} -\item If \tcode{d} is an lvalue or \tcode{const} rvalue then -the first constructor of this pair will be selected. \tcode{D} -shall satisfy the requirements of -\tcode{CopyConstructible} (Table~\ref{tab:copyconstructible}), and -the copy constructor of \tcode{D} shall -not throw an exception. -This \tcode{unique_ptr} will hold -a copy of \tcode{d}. - -\item Otherwise, \tcode{d} is a non-const rvalue and the second -constructor of this pair will be selected. \tcode{D} -shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{tab:moveconstructible}), and the -move constructor of \tcode{D} shall not throw an exception. -This \tcode{unique_ptr} will -hold a value move constructed from \tcode{d}. -\end{itemize} - -\item Otherwise \tcode{D} is an lvalue reference type. \tcode{d} -shall be reference-compatible with one of the constructors. If \tcode{d} is -an rvalue, it will bind to the second constructor of this pair and the program is -ill-formed. \begin{note} The diagnostic could -be implemented using a \tcode{static_assert} which assures that -\tcode{D} is not a reference type. \end{note} Else \tcode{d} -is an lvalue and will bind to the first constructor of this pair. The type -which \tcode{D} references need not be \tcode{CopyConstructible} -nor \tcode{MoveConstructible}. This \tcode{unique_ptr} will -hold a \tcode{D} which refers to the lvalue \tcode{d}. -\begin{note} \tcode{D} may not be an rvalue reference type. -\end{note} -\end{itemize} +\effects Constructs a \tcode{unique_ptr} object which owns \tcode{p}, initializing +the stored pointer with \tcode{p} and initializing the deleter +from \tcode{std::forward(d)}. \pnum -\effects Constructs a \tcode{unique_ptr} object which owns \tcode{p}, initializing -the stored pointer with \tcode{p} and initializing the deleter as described above. +\remarks These constructors shall not participate in overload resolution +unless \tcode{is_constructible_v} is \tcode{true}. \pnum \postconditions \tcode{get() == p}. @@ -8570,8 +8713,13 @@ deleter. If \tcode{D} is a reference type then \tcode{get_deleter()} returns a reference to the lvalue \tcode{d}. -\begin{example} +\pnum +\remarks If class template argument deduction~(\ref{over.match.class.deduct}) +would select a function template corresponding to either of these constructors, +then the program is ill-formed. +\pnum +\begin{example} \begin{codeblock} D d; unique_ptr p1(new int, D()); // \tcode{D} must be \tcode{MoveConstructible} @@ -8580,9 +8728,7 @@ unique_ptr p4(new int, D()); // error: rvalue deleter object combined // with reference deleter type \end{codeblock} - \end{example} - \end{itemdescr} \indexlibrary{\idxcode{unique_ptr}!constructor}% @@ -8885,7 +9031,7 @@ unique_ptr(unique_ptr&& u) noexcept; template unique_ptr(unique_ptr&& u) noexcept; - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr unique_ptr(nullptr_t) noexcept; // destructor ~unique_ptr(); @@ -8950,6 +9096,26 @@ \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} template explicit unique_ptr(U p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +This constructor behaves the same as +the constructor in the primary template that +takes a single parameter of type \tcode{pointer} +except that it additionally +shall not participate in overload resolution unless + +\begin{itemize} +\item \tcode{U} is the same type as \tcode{pointer}, or +\item \tcode{pointer} is the same type as \tcode{element_type*}, +\tcode{U} is a pointer type \tcode{V*}, and +\tcode{V(*)[]} is convertible to \tcode{element_type(*)[]}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{unique_ptr}!constructor}% +\begin{itemdecl} template unique_ptr(U p, @\seebelow@ d) noexcept; template unique_ptr(U p, @\seebelow@ d) noexcept; \end{itemdecl} @@ -8957,8 +9123,8 @@ \begin{itemdescr} \pnum These constructors behave the same as -the constructors that take a \tcode{pointer} parameter -in the primary template +the constructors in the primary template that +take a parameter of type \tcode{pointer} and a second parameter except that they shall not participate in overload resolution unless either @@ -9393,17 +9559,20 @@ element_type& operator[](ptrdiff_t i) const; long use_count() const noexcept; explicit operator bool() const noexcept; - template bool owner_before(const shared_ptr& b) const; - template bool owner_before(const weak_ptr& b) const; + template bool owner_before(const shared_ptr& b) const noexcept; + template bool owner_before(const weak_ptr& b) const noexcept; }; - // \ref{util.smartptr.shared.create}, shared_ptr creation + template shared_ptr(weak_ptr) -> shared_ptr; + template shared_ptr(unique_ptr) -> shared_ptr; + + // \ref{util.smartptr.shared.create}, \tcode{shared_ptr} creation template shared_ptr make_shared(Args&&... args); template shared_ptr allocate_shared(const A& a, Args&&... args); - // \ref{util.smartptr.shared.cmp}, shared_ptr comparisons + // \ref{util.smartptr.shared.cmp}, \tcode{shared_ptr} comparisons template bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; template @@ -9442,11 +9611,11 @@ template bool operator>=(nullptr_t, const shared_ptr& b) noexcept; - // \ref{util.smartptr.shared.spec}, shared_ptr specialized algorithms + // \ref{util.smartptr.shared.spec}, \tcode{shared_ptr} specialized algorithms template void swap(shared_ptr& a, shared_ptr& b) noexcept; - // \ref{util.smartptr.shared.cast}, shared_ptr casts + // \ref{util.smartptr.shared.cast}, \tcode{shared_ptr} casts template shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; template @@ -9456,11 +9625,11 @@ template shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; - // \ref{util.smartptr.getdeleter}, shared_ptr get_deleter + // \ref{util.smartptr.getdeleter}, \tcode{shared_ptr} \tcode{get_deleter} template D* get_deleter(const shared_ptr& p) noexcept; - // \ref{util.smartptr.shared.io}, shared_ptr I/O + // \ref{util.smartptr.shared.io}, \tcode{shared_ptr} I/O template basic_ostream& operator<< (basic_ostream& os, const shared_ptr& p); } @@ -9478,7 +9647,7 @@ \begin{example} \begin{codeblock} if (shared_ptr px = dynamic_pointer_cast(py)) { - // do something with px + // do something with \tcode{px} } \end{codeblock} \end{example} @@ -9534,11 +9703,8 @@ \pnum\requires \tcode{Y} shall be a complete type. The expression \tcode{delete[] p}, when \tcode{T} is an array type, or \tcode{delete p}, when \tcode{T} is not an array type, -shall be well formed, shall have well defined behavior, and +shall have well-defined behavior, and shall not throw exceptions. -When \tcode{T} is \tcode{U[N]}, \tcode{Y(*)[N]} shall be convertible to \tcode{T*}; -when \tcode{T} is \tcode{U[]}, \tcode{Y(*)[]} shall be convertible to \tcode{T*}; -otherwise, \tcode{Y*} shall be convertible to \tcode{T*}. \pnum\effects When \tcode{T} is not an array type, constructs a \tcode{shared_ptr} object @@ -9555,6 +9721,16 @@ \pnum\throws \tcode{bad_alloc}, or an \impldef{exception type when \tcode{shared_ptr} constructor fails} exception when a resource other than memory could not be obtained. + +\pnum\remarks When \tcode{T} is an array type, +this constructor shall not participate in overload resolution unless +the expression \tcode{delete[] p} is well-formed and either +\tcode{T} is \tcode{U[N]} and \tcode{Y(*)[N]} is convertible to \tcode{T*}, or +\tcode{T} is \tcode{U[]} and \tcode{Y(*)[]} is convertible to \tcode{T*}. +When \tcode{T} is not an array type, +this constructor shall not participate in overload resolution unless +the expression \tcode{delete p} is well-formed and +\tcode{Y*} is convertible to \tcode{T*}. \end{itemdescr} \indexlibrary{\idxcode{shared_ptr}!constructor}% @@ -9566,16 +9742,11 @@ \end{itemdecl} \begin{itemdescr} -\pnum\requires \tcode{D} shall be -\tcode{CopyConstructible} and such construction shall not throw exceptions. -The destructor of \tcode{D} -shall not throw exceptions. The expression \tcode{d(p)} shall be -well formed, shall have well defined behavior, and shall not throw exceptions. +\pnum\requires Construction of \tcode{d} and a deleter of type \tcode{D} +initialized with \tcode{std::move(d)} shall not throw exceptions. +The expression \tcode{d(p)} +shall have well-defined behavior and shall not throw exceptions. \tcode{A} shall be an allocator~(\ref{allocator.requirements}). -The copy constructor and destructor of \tcode{A} shall not throw exceptions. -When \tcode{T} is \tcode{U[N]}, \tcode{Y(*)[N]} shall be convertible to \tcode{T*}; -when \tcode{T} is \tcode{U[]}, \tcode{Y(*)[]} shall be convertible to \tcode{T*}; -otherwise, \tcode{Y*} shall be convertible to \tcode{T*}. \pnum\effects Constructs a \tcode{shared_ptr} object that owns the object \tcode{p} and the deleter \tcode{d}. @@ -9590,6 +9761,19 @@ \pnum\throws \tcode{bad_alloc}, or an \impldef{exception type when \tcode{shared_ptr} constructor fails} exception when a resource other than memory could not be obtained. + +\pnum\remarks +When \tcode{T} is an array type, +this constructor shall not participate in overload resolution unless +\tcode{is_move_constructible_v} is \tcode{true}, +the expression \tcode{d(p)} is well-formed, and either +\tcode{T} is \tcode{U[N]} and \tcode{Y(*)[N]} is convertible to \tcode{T*}, or +\tcode{T} is \tcode{U[]} and \tcode{Y(*)[]} is convertible to \tcode{T*}. +When \tcode{T} is not an array type, +this constructor shall not participate in overload resolution unless +\tcode{is_move_constructible_v} is \tcode{true}, +the expression \tcode{d(p)} is well-formed, and +\tcode{Y*} is convertible to \tcode{T*}. \end{itemdescr} \indexlibrary{\idxcode{shared_ptr}!constructor}% @@ -9659,8 +9843,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum\requires \tcode{Y*} shall be compatible with \tcode{T*}. - \pnum\effects Constructs a \tcode{shared_ptr} object that shares ownership with \tcode{r} and stores a copy of the pointer stored in \tcode{r}. If an exception is thrown, the constructor has no effect. @@ -9668,6 +9850,9 @@ \pnum\postconditions \tcode{use_count() == r.use_count()}. \pnum\throws \tcode{bad_weak_ptr} when \tcode{r.expired()}. + +\pnum\remarks This constructor shall not participate in overload resolution unless +\tcode{Y*} is compatible with \tcode{T*}. \end{itemdescr} \indexlibrary{\idxcode{shared_ptr}!constructor}% @@ -9926,8 +10111,8 @@ \indexlibrarymember{owner_before}{shared_ptr}% \begin{itemdecl} -template bool owner_before(const shared_ptr& b) const; -template bool owner_before(const weak_ptr& b) const; +template bool owner_before(const shared_ptr& b) const noexcept; +template bool owner_before(const weak_ptr& b) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -10019,9 +10204,7 @@ \begin{itemdescr} \pnum -\returns \tcode{less()(a.get(), b.get())}, -where \tcode{V} is the composite pointer type (Clause~\ref{expr}) -of \tcode{shared_ptr::element_type*} and \tcode{shared_ptr::element_type*}. +\returns \tcode{less<>()(a.get(), b.get())}. \pnum \begin{note} @@ -10312,6 +10495,9 @@ template bool owner_before(const weak_ptr& b) const; }; + template weak_ptr(shared_ptr) -> weak_ptr; + + // \ref{util.smartptr.weak.spec}, specialized algorithms template void swap(weak_ptr& a, weak_ptr& b) noexcept; } @@ -10502,32 +10688,32 @@ The class template \tcode{owner_less} allows ownership-based mixed comparisons of shared and weak pointers. -\indexlibrary{\idxcode{struct owner_less}}% +\indexlibrary{\idxcode{owner_less}}% \begin{codeblock} namespace std { template struct owner_less; template struct owner_less> { - bool operator()(const shared_ptr&, const shared_ptr&) const; - bool operator()(const shared_ptr&, const weak_ptr&) const; - bool operator()(const weak_ptr&, const shared_ptr&) const; + bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; + bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; + bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; }; template struct owner_less> { - bool operator()(const weak_ptr&, const weak_ptr&) const; - bool operator()(const shared_ptr&, const weak_ptr&) const; - bool operator()(const weak_ptr&, const shared_ptr&) const; + bool operator()(const weak_ptr&, const weak_ptr&) const noexcept; + bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; + bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; }; template<> struct owner_less { template - bool operator()(const shared_ptr&, const shared_ptr&) const; + bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; template - bool operator()(const shared_ptr&, const weak_ptr&) const; + bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; template - bool operator()(const weak_ptr&, const shared_ptr&) const; + bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; template - bool operator()(const weak_ptr&, const weak_ptr&) const; + bool operator()(const weak_ptr&, const weak_ptr&) const noexcept; using is_transparent = @\unspec@; }; @@ -10859,6 +11045,7 @@ 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} \indexlibrary{\idxcode{hash}!\idxcode{shared_ptr}}% @@ -12208,6 +12395,10 @@ scoped_allocator_adaptor select_on_container_copy_construction() const; }; + template + scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) + -> scoped_allocator_adaptor; + template bool operator==(const scoped_allocator_adaptor& a, const scoped_allocator_adaptor& b) noexcept; @@ -12303,14 +12494,15 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{OuterAlloc} shall be constructible from \tcode{OuterA2}. - \pnum \effects Initializes the \tcode{OuterAlloc} base class with \tcode{std::forward(outerAlloc)} and \tcode{inner} with \tcode{innerAllocs...} (hence recursively initializing each allocator within the adaptor with the corresponding allocator from the argument list). + +\pnum +\remarks This constructor shall not participate in overload resolution unless +\tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% @@ -12343,12 +12535,13 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{OuterAlloc} shall be constructible from \tcode{OuterA2}. - \pnum \effects Initializes each allocator within the adaptor with the corresponding allocator from \tcode{other}. + +\pnum +\remarks This constructor shall not participate in overload resolution unless +\tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} \indexlibrary{\idxcode{scoped_allocator_adaptor}!constructor}% @@ -12359,12 +12552,13 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires \tcode{OuterAlloc} shall be constructible from \tcode{OuterA2}. - \pnum \effects Initializes each allocator within the adaptor with the corresponding allocator rvalue from \tcode{other}. + +\pnum +\remarks This constructor shall not participate in overload resolution unless +\tcode{is_constructible_v} is \tcode{true}. \end{itemdescr} \rSec2[allocator.adaptor.members]{Scoped allocator adaptor members} @@ -12713,9 +12907,10 @@ namespace std { // \ref{func.invoke}, invoke template - result_of_t invoke(F&& f, Args&&... args); + invoke_result_t invoke(F&& f, Args&&... args) + noexcept(is_nothrow_invocable_v); - // \ref{refwrap}, reference_wrapper + // \ref{refwrap}, \tcode{reference_wrapper} template class reference_wrapper; template reference_wrapper ref(T&) noexcept; @@ -12831,49 +13026,15 @@ class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher; - template> - default_searcher - make_default_searcher( - ForwardIterator pat_first, - ForwardIterator pat_last, - BinaryPredicate pred = BinaryPredicate()); - - template::value_type>, - class BinaryPredicate = equal_to<>> - boyer_moore_searcher - make_boyer_moore_searcher( - RandomAccessIterator pat_first, - RandomAccessIterator pat_last, - Hash hf = Hash(), - BinaryPredicate pred = BinaryPredicate()); - - template::value_type>, - class BinaryPredicate = equal_to<>> - boyer_moore_horspool_searcher - make_boyer_moore_horspool_searcher( - RandomAccessIterator pat_first, - RandomAccessIterator pat_last, - Hash hf = Hash(), - BinaryPredicate pred = BinaryPredicate()); - // \ref{unord.hash}, hash function primary template template struct hash; - // \ref{func.default.traits}, default functor traits - template - struct default_order; - - template - using default_order_t = typename default_order::type; - // \ref{func.bind}, function object binders template - constexpr bool is_bind_expression_v = is_bind_expression::value; + inline constexpr bool is_bind_expression_v = is_bind_expression::value; template - constexpr int is_placeholder_v = is_placeholder::value; + inline constexpr int is_placeholder_v = is_placeholder::value; } \end{codeblock} @@ -12932,8 +13093,8 @@ \rSec2[func.require]{Requirements} \pnum -\indexlibrary{invoke@\tcode{\textit{INVOKE}}}% -Define \tcode{\textit{INVOKE}(f, t1, t2, ..., tN)} as follows: +\indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% +Define \tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)} as follows: \begin{itemize} \item \tcode{(t1.*f)(t2, ..., tN)} when \tcode{f} is a pointer to a @@ -12964,11 +13125,11 @@ \end{itemize} \pnum -\indexlibrary{invoke@\tcode{\textit{INVOKE}}}% -Define \tcode{\textit{INVOKE}(f, t1, t2, ..., tN, R)} as -\tcode{static_cast(\textit{INVOKE}(f, t1, t2, ..., tN))} +\indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% +Define \tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)} as +\tcode{static_cast(\placeholdernc{INVOKE}(f, t1, t2, ..., tN))} if \tcode{R} is \cv{}~\tcode{void}, otherwise -\tcode{\textit{INVOKE}(f, t1, t2, ..., tN)} implicitly converted +\tcode{\placeholdernc{INVOKE}(f, t1, t2, ..., tN)} implicitly converted to \tcode{R}. \pnum @@ -13001,16 +13162,17 @@ \rSec2[func.invoke]{Function template \tcode{invoke}} \indexlibrary{\idxcode{invoke}}% -\indexlibrary{invoke@\tcode{\textit{INVOKE}}}% +\indexlibrary{invoke@\tcode{\placeholder{INVOKE}}}% \begin{itemdecl} template - result_of_t invoke(F&& f, Args&&... args); + invoke_result_t invoke(F&& f, Args&&... args) + noexcept(is_nothrow_invocable_v); \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{\textit{INVOKE}(std::forward(f), std::forward(args)...)}~(\ref{func.require}). +\tcode{\placeholdernc{INVOKE}(std::forward(f), std::forward(args)...)}~(\ref{func.require}). \end{itemdescr} \rSec2[refwrap]{Class template \tcode{reference_wrapper}} @@ -13038,9 +13200,12 @@ // invocation template - result_of_t - operator() (ArgTypes&&...) const; + invoke_result_t + operator() (ArgTypes&&...) const; }; + + template + reference_wrapper(reference_wrapper) -> reference_wrapper; } \end{codeblock} @@ -13111,12 +13276,12 @@ \indexlibrarymember{operator()}{reference_wrapper}% \begin{itemdecl} template - result_of_t + invoke_result_t operator()(ArgTypes&&... args) const; \end{itemdecl} \begin{itemdescr} -\pnum\returns \tcode{\textit{INVOKE}(get(), std::forward(args)...)}.~(\ref{func.require}) +\pnum\returns \tcode{\placeholdernc{INVOKE}(get(), std::forward(args)...)}.~(\ref{func.require}) \end{itemdescr} @@ -13950,19 +14115,19 @@ template auto operator()(Args&&...) & - -> decltype(!declval>()); + -> decltype(!declval>()); template auto operator()(Args&&...) const& - -> decltype(!declval>()); + -> decltype(!declval>()); template auto operator()(Args&&...) && - -> decltype(!declval>()); + -> decltype(!declval>()); template auto operator()(Args&&...) const&& - -> decltype(!declval>()); + -> decltype(!declval>()); }; \end{codeblock} \end{itemdescr} @@ -13990,10 +14155,10 @@ \begin{itemdecl} template auto operator()(Args&&... args) & - -> decltype(!declval>()); + -> decltype(!declval>()); template auto operator()(Args&&... args) const& - -> decltype(!declval>()); + -> decltype(!declval>()); \end{itemdecl} \begin{itemdescr} @@ -14008,10 +14173,10 @@ \begin{itemdecl} template auto operator()(Args&&... args) && - -> decltype(!declval>()); + -> decltype(!declval>()); template auto operator()(Args&&... args) const&& - -> decltype(!declval>()); + -> decltype(!declval>()); \end{itemdecl} \begin{itemdescr} @@ -14164,7 +14329,7 @@ The effect of \tcode{g($\tcode{u}_1$, $\tcode{u}_2$, \ldots, $\tcode{u}_M$)} shall be \begin{codeblock} -@\placeholdernc{INVOKE}@(fd, std::forward<@$\tcode{V}_1$@>(@$\tcode{v}_1$@), std::forward<@$\tcode{V}_2$@>(@$\tcode{v}_2$@), @\ldots @, std::forward<@$\tcode{V}_N$@>(@$\tcode{v}_N$@), R) +@\placeholdernc{INVOKE}@(fd, std::forward<@$\tcode{V}_1$@>(@$\tcode{v}_1$@), std::forward<@$\tcode{V}_2$@>(@$\tcode{v}_2$@), @\ldots @, std::forward<@$\tcode{V}_N$@>(@$\tcode{v}_N$@)) \end{codeblock} where the values and types of the bound arguments $\tcode{v}_1$, $\tcode{v}_2$, \ldots, $\tcode{v}_N$ are determined as specified below. @@ -14198,7 +14363,7 @@ \item if the value of \tcode{is_bind_expression_v<$\tcode{TD}_i$>} is \tcode{true}, the argument is \tcode{$\tcode{td}_i$(std::forward<$\tcode{U}_j$>($\tcode{u}_j$)...)} and its type $\tcode{V}_i$ is -\tcode{result_of_t<$\tcode{TD}_i$ \cv{} \& ($\tcode{U}_j$\&\&...)>\&\&}; +\tcode{invoke_result_t<$\tcode{TD}_i$ \cv{} \&, $\tcode{U}_j$...>\&\&}; \item if the value \tcode{j} of \tcode{is_placeholder_v<$\tcode{TD}_i$>} is not zero, the argument is \tcode{std::forward<$\tcode{U}_j$>($\tcode{u}_j$)} @@ -14237,7 +14402,7 @@ \pnum Placeholders should be defined as: \begin{codeblock} -constexpr @\unspec@ _1{}; +inline constexpr @\unspec@ _1{}; \end{codeblock} If they are not, they shall be declared as: \begin{codeblock} @@ -14257,7 +14422,7 @@ \pnum \returns A simple call wrapper~(\ref{func.def}) \tcode{fn} such that the expression \tcode{fn(t, a2, ..., aN)} is equivalent -to \tcode{\textit{INVOKE}(pm, t, a2, ..., aN)}~(\ref{func.require}). +to \tcode{\placeholdernc{INVOKE}(pm, t, a2, ..., aN)}~(\ref{func.require}). \end{itemdescr} \indextext{function object!\idxcode{mem_fn}|)} @@ -14343,9 +14508,13 @@ const type_info& target_type() const noexcept; template T* target() noexcept; template const T* target() const noexcept; - }; + template + function(R(*)(ArgTypes...)) -> function; + + template function(F) -> function<@\seebelow@>; + // \ref{func.wrap.func.nullptr}, Null pointer comparisons template bool operator==(const function&, nullptr_t) noexcept; @@ -14378,7 +14547,7 @@ types \tcode{ArgTypes} and return type \tcode{R} if the expression -\tcode{\textit{INVOKE}(declval(), declval()..., R)}, +\tcode{\placeholdernc{INVOKE}(declval(), declval()...)}, considered as an unevaluated operand (Clause~\ref{expr}), is well formed~(\ref{func.require}). @@ -14387,6 +14556,12 @@ wrapper~(\ref{func.def}) whose call signature~(\ref{func.def}) is \tcode{R(ArgTypes...)}. +\pnum +\begin{note} +The types deduced by the deduction guides for \tcode{function} +may change in future versions of this International Standard. +\end{note} + \rSec4[func.wrap.func.con]{\tcode{function} construct/copy/destroy} \indexlibrary{\idxcode{function}!constructor}% @@ -14420,7 +14595,7 @@ \pnum \throws shall not throw exceptions if \tcode{f}'s target is -a callable object passed via \tcode{reference_wrapper} or +a specialization of \tcode{reference_wrapper} or a function pointer. Otherwise, may throw \tcode{bad_alloc} or any exception thrown by the copy constructor of the stored callable object. \begin{note} Implementations are encouraged to avoid the use of @@ -14436,14 +14611,14 @@ \begin{itemdescr} \pnum -\effects If \tcode{!f}, \tcode{*this} has -no target; otherwise, move constructs the target of \tcode{f} -into the target of \tcode{*this}, leaving \tcode{f} in -a valid state with an unspecified value. +\postconditions If \tcode{!f}, \tcode{*this} has no target; +otherwise, the target of \tcode{*this} is equivalent to +the target of \tcode{f} before the construction, and +\tcode{f} is in a valid state with an unspecified value. \pnum \throws shall not throw exceptions if \tcode{f}'s target is -a callable object passed via \tcode{reference_wrapper} or +a specialization of \tcode{reference_wrapper} or a function pointer. Otherwise, may throw \tcode{bad_alloc} or any exception thrown by the copy or move constructor of the stored callable object. @@ -14491,6 +14666,30 @@ or move constructor. \end{itemdescr} + +\begin{itemdecl} +template function(F) -> function<@\seebelow@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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} +for a class type \tcode{G}, then the deduced type is \tcode{function}. + +\pnum +\begin{example} +\begin{codeblock} +void f() { + int i{5}; + function g = [&](double) { return i; }; // deduces \tcode{function} +} +\end{codeblock} +\end{example} +\end{itemdescr} + \indexlibrarymember{operator=}{function}% \begin{itemdecl} function& operator=(const function& f); @@ -14601,7 +14800,7 @@ \begin{itemdescr} \pnum -\returns \tcode{\textit{INVOKE}(f, std::forward(args)..., R)}~(\ref{func.require}), +\returns \tcode{\placeholdernc{INVOKE}(f, std::forward(args)...)}~(\ref{func.require}), where \tcode{f} is the target object~(\ref{func.def}) of \tcode{*this}. \pnum\throws @@ -14701,7 +14900,7 @@ \pnum The Boyer-Moore searcher implements the Boyer-Moore search algorithm. The Boyer-Moore-Horspool searcher implements the Boyer-Moore-Horspool search algorithm. -In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool +In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool. \rSec3[func.search.default]{Class template \tcode{default_searcher}} @@ -14762,25 +14961,6 @@ \end{itemize} \end{itemdescr} -\rSec4[func.search.default.creation]{\tcode{default_searcher} creation functions} - -\indexlibrary{\idxcode{make_default_searcher}}% -\begin{itemdecl} -template > - default_searcher - make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, - BinaryPredicate pred = BinaryPredicate()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return default_searcher(pat_first, pat_last, pred); -\end{codeblock} -\end{itemdescr} - \rSec3[func.search.bm]{Class template \tcode{boyer_moore_searcher}} \indexlibrary{\idxcode{boyer_moore_searcher}}% @@ -14874,30 +15054,6 @@ At most \tcode{(last - first) * (pat_last_ - pat_first_)} applications of the predicate. \end{itemdescr} -\rSec4[func.search.bm.creation]{\tcode{boyer_moore_searcher} creation functions} - -\indexlibrary{\idxcode{make_boyer_moore_searcher}}% -\begin{itemdecl} -template ::value_type>, - class BinaryPredicate = equal_to<>> - boyer_moore_searcher - make_boyer_moore_searcher(RandomAccessIterator pat_first, - RandomAccessIterator pat_last, - Hash hf = Hash(), - BinaryPredicate pred = BinaryPredicate()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return boyer_moore_searcher( - pat_first, pat_last, hf, pred); -\end{codeblock} -\end{itemdescr} - \rSec3[func.search.bmh]{Class template \tcode{boyer_moore_horspool_searcher}} \indexlibrary{\idxcode{boyer_moore_horspool_searcher}}% @@ -14991,30 +15147,6 @@ At most \tcode{(last - first) * (pat_last_ - pat_first_)} applications of the predicate. \end{itemdescr} -\rSec4[func.search.bmh.creation]{\tcode{boyer_moore_horspool_searcher} creation functions} - -\indexlibrary{\idxcode{make_boyer_moore_horspool_searcher}}% -\begin{itemdecl} -template ::value_type>, - class BinaryPredicate = equal_to<>> - boyer_moore_horspool_searcher - make_boyer_moore_horspool_searcher(RandomAccessIterator pat_first, - RandomAccessIterator pat_last, - Hash hf = Hash(), - BinaryPredicate pred = BinaryPredicate()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return boyer_moore_horspool_searcher( - pat_first, pat_last, hf, pred); -\end{codeblock} -\end{itemdescr} - \rSec2[unord.hash]{Class template \tcode{hash}} \pnum @@ -15037,8 +15169,11 @@ For any type \tcode{Key} for which neither the library nor the user provides an explicit or partial specialization of the class template \tcode{hash}, \tcode{hash} is disabled. + +\pnum If the library provides an explicit or partial specialization of \tcode{hash}, -that specialization is enabled except as noted otherwise. +that specialization is enabled except as noted otherwise, +and its member functions are \tcode{noexcept} except as noted otherwise. \pnum If \tcode{H} is a disabled specialization of \tcode{hash}, @@ -15072,50 +15207,6 @@ user-defined specialization that depends on at least one user-defined type. \end{itemize} -\rSec2[func.default.traits]{Default functor traits} - -\indexlibrary{\idxcode{default_order}}% -\begin{codeblock} -namespace std { - template - struct default_order { - using type = less; - }; -} -\end{codeblock} - -\pnum -The class template \tcode{default_order} provides a trait that users can -specialize for user-defined types to provide a strict weak ordering for that -type, which the library can use where a default strict weak order is needed. -For example, the associative containers (\ref{associative}) and -\tcode{priority_queue} (\ref{priority.queue}) use this trait. - -\pnum -\begin{example} -\begin{codeblock} -namespace sales { - struct account { - int id; - std::string name; - }; - - struct order_accounts { - bool operator()(const Account& lhs, const Account& rhs) const { - return lhs.id < rhs.id; - } - }; -} - -namespace std { - template<> - struct default_order { - using type = sales::order_accounts; - }; -} -\end{codeblock} -\end{example} - \rSec1[meta]{Metaprogramming and type traits} \pnum @@ -15130,6 +15221,10 @@ characteristics of types or of combinations of types to be inspected. The type transformations allow certain properties of types to be manipulated. +\pnum +\indextext{signal-safe!type traits}% +All functions specified in this subclause are signal-safe~(\ref{csignal.syn}). + \rSec2[meta.rqmts]{Requirements} \pnum @@ -15221,6 +15316,7 @@ template struct is_polymorphic; template struct is_abstract; template struct is_final; + template struct is_aggregate; template struct is_signed; template struct is_unsigned; @@ -15277,13 +15373,11 @@ template struct is_base_of; template struct is_convertible; - template struct is_callable; // not defined - template - struct is_callable; + template struct is_invocable; + template struct is_invocable_r; - template struct is_nothrow_callable; // not defined - template - struct is_nothrow_callable; + template struct is_nothrow_invocable; + template struct is_nothrow_invocable_r; // \ref{meta.trans.cv}, const-volatile modifications template struct remove_const; @@ -15355,8 +15449,7 @@ template struct conditional; template struct common_type; template struct underlying_type; - template class result_of; // not defined - template class result_of; + template struct invoke_result; template // see \ref{meta.trans.other} @@ -15373,8 +15466,8 @@ using common_type_t = typename common_type::type; template using underlying_type_t = typename underlying_type::type; - template - using result_of_t = typename result_of::type; + template + using invoke_result_t = typename invoke_result::type; template using void_t = void; @@ -15384,161 +15477,167 @@ template struct negation; // \ref{meta.unary.cat}, primary type categories - template constexpr bool is_void_v + template inline constexpr bool is_void_v = is_void::value; - template constexpr bool is_null_pointer_v + template inline constexpr bool is_null_pointer_v = is_null_pointer::value; - template constexpr bool is_integral_v + template inline constexpr bool is_integral_v = is_integral::value; - template constexpr bool is_floating_point_v + template inline constexpr bool is_floating_point_v = is_floating_point::value; - template constexpr bool is_array_v + template inline constexpr bool is_array_v = is_array::value; - template constexpr bool is_pointer_v + template inline constexpr bool is_pointer_v = is_pointer::value; - template constexpr bool is_lvalue_reference_v + template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; - template constexpr bool is_rvalue_reference_v + template inline constexpr bool is_rvalue_reference_v = is_rvalue_reference::value; - template constexpr bool is_member_object_pointer_v + template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer::value; - template constexpr bool is_member_function_pointer_v + template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer::value; - template constexpr bool is_enum_v + template inline constexpr bool is_enum_v = is_enum::value; - template constexpr bool is_union_v + template inline constexpr bool is_union_v = is_union::value; - template constexpr bool is_class_v + template inline constexpr bool is_class_v = is_class::value; - template constexpr bool is_function_v + template inline constexpr bool is_function_v = is_function::value; // \ref{meta.unary.comp}, composite type categories - template constexpr bool is_reference_v + template inline constexpr bool is_reference_v = is_reference::value; - template constexpr bool is_arithmetic_v + template inline constexpr bool is_arithmetic_v = is_arithmetic::value; - template constexpr bool is_fundamental_v + template inline constexpr bool is_fundamental_v = is_fundamental::value; - template constexpr bool is_object_v + template inline constexpr bool is_object_v = is_object::value; - template constexpr bool is_scalar_v + template inline constexpr bool is_scalar_v = is_scalar::value; - template constexpr bool is_compound_v + template inline constexpr bool is_compound_v = is_compound::value; - template constexpr bool is_member_pointer_v + template inline constexpr bool is_member_pointer_v = is_member_pointer::value; // \ref{meta.unary.prop}, type properties - template constexpr bool is_const_v + template inline constexpr bool is_const_v = is_const::value; - template constexpr bool is_volatile_v + template inline constexpr bool is_volatile_v = is_volatile::value; - template constexpr bool is_trivial_v + template inline constexpr bool is_trivial_v = is_trivial::value; - template constexpr bool is_trivially_copyable_v + template inline constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; - template constexpr bool is_standard_layout_v + template inline constexpr bool is_standard_layout_v = is_standard_layout::value; - template constexpr bool is_pod_v + template inline constexpr bool is_pod_v = is_pod::value; - template constexpr bool is_empty_v + template inline constexpr bool is_empty_v = is_empty::value; - template constexpr bool is_polymorphic_v + template inline constexpr bool is_polymorphic_v = is_polymorphic::value; - template constexpr bool is_abstract_v + template inline constexpr bool is_abstract_v = is_abstract::value; - template constexpr bool is_final_v + template inline constexpr bool is_final_v = is_final::value; - template constexpr bool is_signed_v + template inline constexpr bool is_aggregate_v + = is_aggregate::value; + template inline constexpr bool is_signed_v = is_signed::value; - template constexpr bool is_unsigned_v + template inline constexpr bool is_unsigned_v = is_unsigned::value; - template constexpr bool is_constructible_v + template inline constexpr bool is_constructible_v = is_constructible::value; - template constexpr bool is_default_constructible_v + template inline constexpr bool is_default_constructible_v = is_default_constructible::value; - template constexpr bool is_copy_constructible_v + template inline constexpr bool is_copy_constructible_v = is_copy_constructible::value; - template constexpr bool is_move_constructible_v + template inline constexpr bool is_move_constructible_v = is_move_constructible::value; - template constexpr bool is_assignable_v + template inline constexpr bool is_assignable_v = is_assignable::value; - template constexpr bool is_copy_assignable_v + template inline constexpr bool is_copy_assignable_v = is_copy_assignable::value; - template constexpr bool is_move_assignable_v + template inline constexpr bool is_move_assignable_v = is_move_assignable::value; - template constexpr bool is_swappable_with_v + template inline constexpr bool is_swappable_with_v = is_swappable_with::value; - template constexpr bool is_swappable_v + template inline constexpr bool is_swappable_v = is_swappable::value; - template constexpr bool is_destructible_v + template inline constexpr bool is_destructible_v = is_destructible::value; - template constexpr bool is_trivially_constructible_v + template inline constexpr bool is_trivially_constructible_v = is_trivially_constructible::value; - template constexpr bool is_trivially_default_constructible_v + template inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible::value; - template constexpr bool is_trivially_copy_constructible_v + template inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible::value; - template constexpr bool is_trivially_move_constructible_v + template inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible::value; - template constexpr bool is_trivially_assignable_v + template inline constexpr bool is_trivially_assignable_v = is_trivially_assignable::value; - template constexpr bool is_trivially_copy_assignable_v + template inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable::value; - template constexpr bool is_trivially_move_assignable_v + template inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable::value; - template constexpr bool is_trivially_destructible_v + template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible::value; - template constexpr bool is_nothrow_constructible_v + template inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible::value; - template constexpr bool is_nothrow_default_constructible_v + template inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible::value; - template constexpr bool is_nothrow_copy_constructible_v + template inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible::value; - template constexpr bool is_nothrow_move_constructible_v + template inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible::value; - template constexpr bool is_nothrow_assignable_v + template inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable::value; - template constexpr bool is_nothrow_copy_assignable_v + template inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable::value; - template constexpr bool is_nothrow_move_assignable_v + template inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable::value; - template constexpr bool is_nothrow_swappable_with_v + template inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with::value; - template constexpr bool is_nothrow_swappable_v + template inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable::value; - template constexpr bool is_nothrow_destructible_v + template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible::value; - template constexpr bool has_virtual_destructor_v + template inline constexpr bool has_virtual_destructor_v = has_virtual_destructor::value; - template constexpr bool has_unique_object_representations_v + template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations::value; // \ref{meta.unary.prop.query}, type property queries - template constexpr size_t alignment_of_v + template inline constexpr size_t alignment_of_v = alignment_of::value; - template constexpr size_t rank_v + template inline constexpr size_t rank_v = rank::value; - template constexpr size_t extent_v + template inline constexpr size_t extent_v = extent::value; // \ref{meta.rel}, type relations - template constexpr bool is_same_v + template inline constexpr bool is_same_v = is_same::value; - template constexpr bool is_base_of_v + template inline constexpr bool is_base_of_v = is_base_of::value; - template constexpr bool is_convertible_v + template inline constexpr bool is_convertible_v = is_convertible::value; - template constexpr bool is_callable_v - = is_callable::value; - template constexpr bool is_nothrow_callable_v - = is_nothrow_callable::value; + template inline constexpr bool is_invocable_v + = is_invocable::value; + template inline constexpr bool is_invocable_r_v + = is_invocable_r::value; + template inline constexpr bool is_nothrow_invocable_v + = is_nothrow_invocable::value; + template inline constexpr bool is_nothrow_invocable_r_v + = is_nothrow_invocable_r::value; // \ref{meta.logical}, logical operator traits - template constexpr bool conjunction_v = conjunction::value; - template constexpr bool disjunction_v = disjunction::value; - template constexpr bool negation_v = negation::value; + template inline constexpr bool conjunction_v = conjunction::value; + template inline constexpr bool disjunction_v = disjunction::value; + template inline constexpr bool negation_v = negation::value; } \end{codeblock} @@ -15827,6 +15926,12 @@ can be marked with \tcode{final}. \end{note} & If \tcode{T} is a class type, \tcode{T} shall be a complete type. \\ \rowsep +\indexlibrary{\idxcode{is_aggregate_signed}!class}% +\tcode{template }\br + \tcode{struct is_aggregate;} & + \tcode{T} is an aggregate type~(\ref{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{struct is_signed;} & @@ -16166,10 +16271,10 @@ union U2 final { }; // the following assertions hold: -static_assert(!is_final_v, "Error!"); -static_assert( is_final_v

, "Error!"); -static_assert(!is_final_v, "Error!"); -static_assert( is_final_v, "Error!"); +static_assert(!is_final_v); +static_assert(is_final_v

); +static_assert(!is_final_v); +static_assert(is_final_v); \end{codeblock} \end{example} @@ -16328,22 +16433,39 @@ types, arrays of unknown bound, or \cv{}~\tcode{void} types. \\ \rowsep -\indexlibrary{\idxcode{is_callable}}% -\tcode{template }\br - \tcode{struct is_callable<}\br - \tcode{Fn(ArgTypes...), R>;} & - The expression \tcode{\textit{INVOKE}(declval(), declval()..., R)} +\indexlibrary{\idxcode{is_invocable}}% +\tcode{template }\br + \tcode{struct is_invocable;} & + The expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} + is well formed when treated as an unevaluated operand & + \tcode{Fn} and all types in the parameter pack \tcode{ArgTypes} + shall be complete types, \cv{}~\tcode{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibrary{\idxcode{is_invocable_r}}% +\tcode{template }\br + \tcode{struct is_invocable_r;} & + The expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} is well formed when treated as an unevaluated operand & \tcode{Fn}, \tcode{R}, and all types in the parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\tcode{void}, or arrays of unknown bound. \\ \rowsep -\indexlibrary{\idxcode{is_nothrow_callable}}% -\tcode{template }\br - \tcode{struct is_nothrow_callable<}\br - \tcode{Fn(ArgTypes...), R>;} & - \tcode{is_callable_v<}\br\tcode{Fn(ArgTypes...), R>} is \tcode{true} and - the expression \tcode{\textit{INVOKE}(declval(), declval()..., R)} +\indexlibrary{\idxcode{is_nothrow_invocable}}% +\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()...)} + is known not to throw any exceptions & + \tcode{Fn} and all types in the parameter pack \tcode{ArgTypes} + shall be complete types, \cv{}~\tcode{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibrary{\idxcode{is_nothrow_invocable_r}}% +\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()...)} is known not to throw any exceptions & \tcode{Fn}, \tcode{R}, and all types in the parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\tcode{void}, or @@ -16423,7 +16545,7 @@ \indexlibrary{\idxcode{remove_const}}% \tcode{template \br struct remove_const;} & - The member typedef \tcode{type} shall name + The member typedef \tcode{type} names the same type as \tcode{T} except that any top-level const-qualifier has been removed. \begin{example} \tcode{remove_const_t} evaluates @@ -16433,7 +16555,7 @@ \indexlibrary{\idxcode{remove_volatile}}% \tcode{template \br struct remove_volatile;} & - The member typedef \tcode{type} shall name + The member typedef \tcode{type} names the same type as \tcode{T} except that any top-level volatile-qualifier has been removed. \begin{example} \tcode{remove_volatile_t} @@ -16454,7 +16576,7 @@ \tcode{template \br struct add_const;} & If \tcode{T} is a reference, function, or top-level const-qualified - type, then \tcode{type} shall name + type, then \tcode{type} names the same type as \tcode{T}, otherwise \tcode{T const}. \\ \rowsep @@ -16462,14 +16584,14 @@ \tcode{template \br struct add_volatile;} & If \tcode{T} is a reference, function, or top-level volatile-qualified - type, then \tcode{type} shall name + type, then \tcode{type} names the same type as \tcode{T}, otherwise \tcode{T volatile}. \\ \rowsep \indexlibrary{\idxcode{add_cv}}% \tcode{template \br struct add_cv;} & - The member typedef \tcode{type} shall name + The member typedef \tcode{type} names the same type as \tcode{add_const_t{>}}. \\ \end{libreqtab2a} @@ -16489,15 +16611,15 @@ \tcode{template \br struct remove_reference;} & If \tcode{T} has type ``reference to \tcode{T1}'' then the - member typedef \tcode{type} shall name \tcode{T1}; - otherwise, \tcode{type} shall name \tcode{T}.\\ \rowsep + member typedef \tcode{type} names \tcode{T1}; + otherwise, \tcode{type} names \tcode{T}.\\ \rowsep \indexlibrary{\idxcode{add_lvalue_reference}}% \tcode{template \br struct add_lvalue_reference;} & If \tcode{T} names a referenceable type (\ref{defns.referenceable}) then - the member typedef \tcode{type} shall name \tcode{T\&}; - otherwise, \tcode{type} shall name \tcode{T}. + the member typedef \tcode{type} names \tcode{T\&}; + otherwise, \tcode{type} names \tcode{T}. \begin{note} This rule reflects the semantics of reference collapsing~(\ref{dcl.ref}). \end{note}\\ \rowsep @@ -16506,8 +16628,8 @@ \tcode{template }\br \tcode{struct add_rvalue_reference;} & If \tcode{T} names a referenceable type then - the member typedef \tcode{type} shall name \tcode{T\&\&}; - otherwise, \tcode{type} shall name \tcode{T}. + the member typedef \tcode{type} names \tcode{T\&\&}; + otherwise, \tcode{type} names \tcode{T}. \begin{note} This rule reflects the semantics of reference collapsing~(\ref{dcl.ref}). For example, when a type \tcode{T} names a type \tcode{T1\&}, the type \tcode{add_rvalue_reference_t} is not an rvalue reference. @@ -16529,11 +16651,11 @@ \tcode{struct make_signed;} & If \tcode{T} names a (possibly cv-qualified) signed integer type~(\ref{basic.fundamental}) then the member typedef - \tcode{type} shall name the type \tcode{T}; otherwise, + \tcode{type} names the type \tcode{T}; otherwise, if \tcode{T} names a (possibly cv-qualified) unsigned integer - type then \tcode{type} shall name the corresponding + type then \tcode{type} names the corresponding signed integer type, with the same cv-qualifiers as \tcode{T}; - otherwise, \tcode{type} shall name the signed integer type with smallest + otherwise, \tcode{type} names the signed integer type with smallest rank~(\ref{conv.rank}) for which \tcode{sizeof(T) == sizeof(type)}, with the same cv-qualifiers as \tcode{T}.\br @@ -16546,11 +16668,11 @@ \tcode{struct make_unsigned;} & If \tcode{T} names a (possibly cv-qualified) unsigned integer type~(\ref{basic.fundamental}) then the member typedef - \tcode{type} shall name the type \tcode{T}; otherwise, + \tcode{type} names the type \tcode{T}; otherwise, if \tcode{T} names a (possibly cv-qualified) signed integer - type then \tcode{type} shall name the corresponding + type then \tcode{type} names the corresponding unsigned integer type, with the same cv-qualifiers as \tcode{T}; - otherwise, \tcode{type} shall name the unsigned integer type with smallest + otherwise, \tcode{type} names the unsigned integer type with smallest rank~(\ref{conv.rank}) for which \tcode{sizeof(T) == sizeof(type)}, with the same cv-qualifiers as \tcode{T}.\br @@ -16624,16 +16746,16 @@ struct remove_pointer;} & If \tcode{T} has type ``(possibly cv-qualified) pointer to \tcode{T1}'' then the member typedef \tcode{type} - shall name \tcode{T1}; otherwise, it shall name \tcode{T}.\\ \rowsep + names \tcode{T1}; otherwise, it names \tcode{T}.\\ \rowsep \indexlibrary{\idxcode{add_pointer}}% \tcode{template \br struct add_pointer;} & If \tcode{T} names a referenceable type (\ref{defns.referenceable}) or a \cv{}~\tcode{void} type then - the member typedef \tcode{type} shall name the same type as + the member typedef \tcode{type} names the same type as \tcode{remove_reference_t*}; - otherwise, \tcode{type} shall name \tcode{T}. \\ + otherwise, \tcode{type} names \tcode{T}. \\ \end{libreqtab2a} \clearpage @@ -16717,19 +16839,18 @@ \tcode{template }\br \tcode{struct underlying_type;} & - The member typedef \tcode{type} shall name the underlying type + The member typedef \tcode{type} names the underlying type of \tcode{T}.\br \requires{} \tcode{T} shall be a complete enumeration type~(\ref{dcl.enum}) \\ \rowsep \tcode{template }\br - \tcode{struct result_of<}\br - \tcode{Fn(ArgTypes...)>;} + \tcode{struct invoke_result;} & - If the expression \tcode{\textit{INVOKE}(declval(), declval()...)} + If the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} is well formed when treated as an unevaluated operand (Clause~\ref{expr}), - the member typedef \tcode{type} shall name the type - \tcode{decltype(\textit{INVOKE}(declval(), declval()...))}; + 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 performed as if in a context unrelated to \tcode{Fn} and \tcode{ArgTypes}. Only the validity of the immediate context of the @@ -16776,7 +16897,8 @@ \item If \tcode{sizeof...(T)} is one, let \tcode{T0} denote the sole type constituting the pack \tcode{T}. The member \grammarterm{typedef-name} \tcode{type} shall denote the same -type as \tcode{decay_t}. +type, if any, as \tcode{common_type_t}; +otherwise there shall be no member \tcode{type}. \item If \tcode{sizeof...(T)} is two, let the first and second types constituting \tcode{T} be denoted @@ -16798,10 +16920,6 @@ In either case, the member \grammarterm{typedef-name} \tcode{type} shall denote the same type, if any, as \tcode{C}. Otherwise, there shall be no member \tcode{type}. -\begin{note} -When \tcode{is_same_v} is \tcode{true}, -the effect is equivalent to that of \tcode{common_type}. -\end{note} \item If \tcode{sizeof...(T)} is greater than two, let \tcode{T1}, \tcode{T2}, and \tcode{R}, respectively, @@ -16816,7 +16934,7 @@ Note B: Notwithstanding the provisions of \ref{meta.type.synop}, and pursuant to \ref{namespace.std}, a program may specialize \tcode{common_type} -for distinct types \tcode{T1} and \tcode{T2} such that +for types \tcode{T1} and \tcode{T2} such that \tcode{is_same_v>} and \tcode{is_same_v>} are each \tcode{true}. \begin{note} @@ -16852,12 +16970,12 @@ the following assertions will hold: \begin{codeblock} -static_assert(is_same_v, short>, "Error!"); -static_assert(is_same_v, double>, "Error!"); -static_assert(is_same_v, bool>, "Error!"); -static_assert(is_same_v, int)>, void>, "Error!"); -static_assert(is_same_v, char&&>, "Error!"); -static_assert(is_same_v, const char&>, "Error!"); +static_assert(is_same_v, short>); +static_assert(is_same_v, double>); +static_assert(is_same_v, bool>); +static_assert(is_same_v, int>, void>); +static_assert(is_same_v, char&&>); +static_assert(is_same_v, const char&>); \end{codeblock} \end{example} @@ -17017,17 +17135,17 @@ template struct ratio_greater_equal; template - constexpr bool ratio_equal_v = ratio_equal::value; + inline constexpr bool ratio_equal_v = ratio_equal::value; template - constexpr bool ratio_not_equal_v = ratio_not_equal::value; + inline constexpr bool ratio_not_equal_v = ratio_not_equal::value; template - constexpr bool ratio_less_v = ratio_less::value; + inline constexpr bool ratio_less_v = ratio_less::value; template - constexpr bool ratio_less_equal_v = ratio_less_equal::value; + inline constexpr bool ratio_less_equal_v = ratio_less_equal::value; template - constexpr bool ratio_greater_v = ratio_greater::value; + inline constexpr bool ratio_greater_v = ratio_greater::value; template - constexpr bool ratio_greater_equal_v = ratio_greater_equal::value; + inline constexpr bool ratio_greater_equal_v = ratio_greater_equal::value; // \ref{ratio.si}, convenience SI typedefs using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; // see below @@ -17249,10 +17367,10 @@ // \ref{time.traits}, customization traits template struct treat_as_floating_point; template struct duration_values; - template constexpr bool treat_as_floating_point_v + template inline constexpr bool treat_as_floating_point_v = treat_as_floating_point::value; - // \ref{time.duration.nonmember}, duration arithmetic + // \ref{time.duration.nonmember}, \tcode{duration} arithmetic template common_type_t, duration> constexpr operator+(const duration& lhs, @@ -17282,7 +17400,7 @@ constexpr operator%(const duration& lhs, const duration& rhs); - // \ref{time.duration.comparisons}, duration comparisons + // \ref{time.duration.comparisons}, \tcode{duration} comparisons template constexpr bool operator==(const duration& lhs, const duration& rhs); @@ -17302,7 +17420,7 @@ constexpr bool operator>=(const duration& lhs, const duration& rhs); - // \ref{time.duration.cast}, duration_cast + // \ref{time.duration.cast}, \tcode{duration_cast} template constexpr ToDuration duration_cast(const duration& d); template @@ -17320,7 +17438,7 @@ using minutes = duration<@\term{signed integer type of at least 29 bits}@, ratio< 60>>; using hours = duration<@\term{signed integer type of at least 23 bits}@, ratio<3600>>; - // \ref{time.point.nonmember}, time_point arithmetic + // \ref{time.point.nonmember}, \tcode{time_point} arithmetic template constexpr time_point>> operator+(const time_point& lhs, @@ -17338,7 +17456,7 @@ operator-(const time_point& lhs, const time_point& rhs); - // \ref{time.point.comparisons}, time_point comparisons + // \ref{time.point.comparisons}, \tcode{time_point} comparisons template constexpr bool operator==(const time_point& lhs, const time_point& rhs); @@ -17358,7 +17476,7 @@ constexpr bool operator>=(const time_point& lhs, const time_point& rhs); - // \ref{time.point.cast}, time_point_cast + // \ref{time.point.cast}, \tcode{time_point_cast} template constexpr time_point time_point_cast(const time_point& t); @@ -17385,18 +17503,18 @@ inline namespace literals { inline namespace chrono_literals { // \ref{time.duration.literals}, suffixes for duration literals - constexpr chrono::hours operator "" h(unsigned long long); - constexpr chrono::duration<@\unspec,@ ratio<3600,1>> operator "" h(long double); - constexpr chrono::minutes operator "" min(unsigned long long); - constexpr chrono::duration<@\unspec,@ ratio<60,1>> operator "" min(long double); - constexpr chrono::seconds operator "" s(unsigned long long); - constexpr chrono::duration<@\unspec@> @\itcorr[-1]@ operator "" s(long double); - constexpr chrono::milliseconds operator "" ms(unsigned long long); - constexpr chrono::duration<@\unspec,@ milli> operator "" ms(long double); - constexpr chrono::microseconds operator "" us(unsigned long long); - constexpr chrono::duration<@\unspec,@ micro> operator "" us(long double); - constexpr chrono::nanoseconds operator "" ns(unsigned long long); - constexpr chrono::duration<@\unspec,@ nano> operator "" ns(long double); + constexpr chrono::hours operator""h(unsigned long long); + constexpr chrono::duration<@\unspec,@ ratio<3600,1>> operator""h(long double); + constexpr chrono::minutes operator""min(unsigned long long); + constexpr chrono::duration<@\unspec,@ ratio<60,1>> operator""min(long double); + constexpr chrono::seconds operator""s(unsigned long long); + constexpr chrono::duration<@\unspec@> @\itcorr[-1]@ operator""s(long double); + constexpr chrono::milliseconds operator""ms(unsigned long long); + constexpr chrono::duration<@\unspec,@ milli> operator""ms(long double); + constexpr chrono::microseconds operator""us(unsigned long long); + constexpr chrono::duration<@\unspec,@ micro> operator""us(long double); + constexpr chrono::nanoseconds operator""ns(unsigned long long); + constexpr chrono::duration<@\unspec,@ nano> operator""ns(long double); } } @@ -17629,7 +17747,7 @@ class duration { public: using rep = Rep; - using period = Period; + using period = typename Period::type; private: rep rep_; // \expos public: @@ -17647,8 +17765,8 @@ constexpr rep count() const; // \ref{time.duration.arithmetic}, arithmetic - constexpr duration operator+() const; - constexpr duration operator-() const; + constexpr common_type_t operator+() const; + constexpr common_type_t operator-() const; constexpr duration& operator++(); constexpr duration operator++(int); constexpr duration& operator--(); @@ -17774,22 +17892,22 @@ \indexlibrarymember{operator+}{duration}% \begin{itemdecl} -constexpr duration operator+() const; +constexpr common_type_t operator+() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{*this}. +\returns \tcode{common_type_t(*this)}. \end{itemdescr} \indexlibrarymember{operator-}{duration}% \begin{itemdecl} -constexpr duration operator-() const; +constexpr common_type_t operator-() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{duration(-rep_)}. +\returns \tcode{common_type_t(-rep_)}. \end{itemdescr} \indexlibrarymember{operator++}{duration}% @@ -18282,10 +18400,10 @@ \end{codeblock} \end{example} -\indexlibrarymember{operator """" h}{duration}% +\indexlibrarymember{operator""""h}{duration}% \begin{itemdecl} -constexpr chrono::hours operator "" h(unsigned long long hours); -constexpr chrono::duration<@\unspec,@ ratio<3600, 1>> operator "" h(long double hours); +constexpr chrono::hours operator""h(unsigned long long hours); +constexpr chrono::duration<@\unspec,@ ratio<3600, 1>> operator""h(long double hours); \end{itemdecl} \begin{itemdescr} @@ -18294,10 +18412,10 @@ A \tcode{duration} literal representing \tcode{hours} hours. \end{itemdescr} -\indexlibrarymember{operator """" min}{duration}% +\indexlibrarymember{operator""""min}{duration}% \begin{itemdecl} -constexpr chrono::minutes operator "" min(unsigned long long minutes); -constexpr chrono::duration<@\unspec,@ ratio<60, 1>> operator "" min(long double minutes); +constexpr chrono::minutes operator""min(unsigned long long minutes); +constexpr chrono::duration<@\unspec,@ ratio<60, 1>> operator""min(long double minutes); \end{itemdecl} \begin{itemdescr} @@ -18306,10 +18424,10 @@ A \tcode{duration} literal representing \tcode{minutes} minutes. \end{itemdescr} -\indexlibrarymember{operator """" s}{duration}% +\indexlibrarymember{operator""""s}{duration}% \begin{itemdecl} -constexpr chrono::seconds @\itcorr@ operator "" s(unsigned long long sec); -constexpr chrono::duration<@\unspec@> operator "" s(long double sec); +constexpr chrono::seconds @\itcorr@ operator""s(unsigned long long sec); +constexpr chrono::duration<@\unspec@> operator""s(long double sec); \end{itemdecl} \begin{itemdescr} @@ -18325,10 +18443,10 @@ \end{note} \end{itemdescr} -\indexlibrarymember{operator """" ms}{duration}% +\indexlibrarymember{operator""""ms}{duration}% \begin{itemdecl} -constexpr chrono::milliseconds operator "" ms(unsigned long long msec); -constexpr chrono::duration<@\unspec,@ milli> operator "" ms(long double msec); +constexpr chrono::milliseconds operator""ms(unsigned long long msec); +constexpr chrono::duration<@\unspec,@ milli> operator""ms(long double msec); \end{itemdecl} \begin{itemdescr} @@ -18337,10 +18455,10 @@ A \tcode{duration} literal representing \tcode{msec} milliseconds. \end{itemdescr} -\indexlibrarymember{operator """" us}{duration}% +\indexlibrarymember{operator""""us}{duration}% \begin{itemdecl} -constexpr chrono::microseconds operator "" us(unsigned long long usec); -constexpr chrono::duration<@\unspec,@ micro> operator "" us(long double usec); +constexpr chrono::microseconds operator""us(unsigned long long usec); +constexpr chrono::duration<@\unspec,@ micro> operator""us(long double usec); \end{itemdecl} \begin{itemdescr} @@ -18349,10 +18467,10 @@ A \tcode{duration} literal representing \tcode{usec} microseconds. \end{itemdescr} -\indexlibrarymember{operator """" ns}{duration}% +\indexlibrarymember{operator""""ns}{duration}% \begin{itemdecl} -constexpr chrono::nanoseconds operator "" ns(unsigned long long nsec); -constexpr chrono::duration<@\unspec,@ nano> operator "" ns(long double nsec); +constexpr chrono::nanoseconds operator""ns(unsigned long long nsec); +constexpr chrono::duration<@\unspec,@ nano> operator""ns(long double nsec); \end{itemdecl} \begin{itemdescr} @@ -18396,7 +18514,7 @@ public: // \ref{time.point.cons}, construct constexpr time_point(); // has value epoch - constexpr explicit time_point(const duration& d); // same as time_point() + d + constexpr explicit time_point(const duration& d); // same as \tcode{time_point() + d} template constexpr time_point(const time_point& t); @@ -19095,7 +19213,7 @@ namespace std { // \ref{execpol.type}, execution policy type trait template struct is_execution_policy; - template constexpr bool is_execution_policy_v = is_execution_policy::value; + template inline constexpr bool is_execution_policy_v = is_execution_policy::value; } namespace std::execution { @@ -19109,9 +19227,9 @@ class parallel_unsequenced_policy; // \ref{execpol.objects}, execution policy objects - constexpr sequenced_policy seq{ @\unspec@ }; - constexpr parallel_policy par{ @\unspec@ }; - constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; + inline constexpr sequenced_policy seq{ @\unspec@ }; + inline constexpr parallel_policy par{ @\unspec@ }; + inline constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; } \end{codeblock} @@ -19214,9 +19332,9 @@ \indexlibrary{\idxcode{execution}!\idxcode{par}}% \indexlibrary{\idxcode{execution}!\idxcode{par_unseq}}% \begin{itemdecl} -constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; -constexpr execution::parallel_policy execution::par{ @\unspec@ }; -constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; +inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; +inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; +inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; \end{itemdecl} \begin{itemdescr} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex new file mode 100644 index 0000000000..a89058b8fd --- /dev/null +++ b/source/xrefdelta.tex @@ -0,0 +1,115 @@ +%!TEX root = std.tex + +\newcommand{\secref}[1]{\hyperref[\indexescape{#1}]{\indexescape{#1}}} + +% Turn off page numbers for this glossary, they're not useful. +\newcommand{\swallow}[1]{} +\changeglossnumformat[xrefdelta]{|swallow} + +\newcommand{\oldxref}[2]{\glossary[xrefdelta]{\indexescape{#1}}{#2}} +\newcommand{\removedxref}[1]{\oldxref{#1}{\textit{removed}}} +\newcommand{\movedxrefs}[2]{\oldxref{#1}{\textit{see} #2}} +\newcommand{\movedxref}[2]{\movedxrefs{#1}{\secref{#2}}} +\newcommand{\movedxrefii}[3]{\movedxrefs{#1}{\secref{#2}, \secref{#3}}} +\newcommand{\movedxrefiii}[4]{\movedxrefs{#1}{\secref{#2}, \secref{#3}, \secref{#4}}} +\newcommand{\deprxref}[1]{\oldxref{#1}{\textit{see} \secref{depr.#1}}} + +% Removed features. +\removedxref{depr.auto.ptr} +\removedxref{auto.ptr} +\removedxref{auto.ptr.cons} +\removedxref{auto.ptr.conv} +\removedxref{auto.ptr.members} +\removedxref{depr.incr.bool} +\removedxref{exception.unexpected} +\removedxref{except.unexpected} +\removedxref{get.unexpected} +\removedxref{set.unexpected} +\removedxref{unexpected} +\removedxref{unexpected.handler} +\removedxref{depr.adaptors} +\removedxref{depr.base} +\removedxref{depr.function.objects} +\removedxref{depr.function.pointer.adaptors} +\removedxref{depr.lib.bind.1st} +\removedxref{depr.lib.bind.2nd} +\removedxref{depr.lib.binder.1st} +\removedxref{depr.lib.binder.2nd} +\removedxref{depr.lib.binders} +\removedxref{depr.member.pointer.adaptors} +\removedxref{depr.ios.members} +\removedxref{depr.alg.random.shuffle} +\removedxref{depr.register} +\removedxref{lex.trigraph} + +% Renamed sections. +\movedxref{atomics.types.operations.arith}{atomics.types.int} +\movedxref{atomics.types.operations.general}{atomics.types.operations} +\movedxref{atomics.types.operations.pointer}{atomics.types.pointer} +\movedxref{atomics.types.operations.req}{atomics.types.operations} +\movedxref{atomics.types.operations.templ}{atomics.types.operations} +\movedxrefii{basic.start.init}{basic.start.static}{basic.start.dynamic} +\movedxref{bind}{func.bind} +\movedxref{charname}{lex.name} +\movedxrefs{charname.allowed}{Table~\ref{tab:charname.allowed}} +\movedxrefs{charname.disallowed}{Table~\ref{tab:charname.disallowed}} +\movedxrefii{class.inhctor}{class.inhctor.init}{namespace.udecl} +\movedxref{c.limits}{climits.syn} +\movedxref{date.time}{ctime.syn} +\movedxref{defns.additional}{definitions} +\movedxref{expr.prim.general}{expr.prim} +\movedxref{fstreams}{fstream.syn} +\movedxref{global.names}{lex.name} +\movedxrefiii{iostream.format.overview}{istream.syn}{ostream.syn}{iomanip.syn} +\movedxref{iostreams.base.overview}{ios.syn} +\movedxref{limits}{support.limits} +\movedxrefii{limits.numeric}{support.limits.general}{limits.syn} +\movedxref{stream.buffers.overview}{streambuf.syn} +\movedxref{string.streams.overview}{sstream.syn} +\movedxref{uninitialized.fill.n}{uninitialized.fill} +\movedxref{util.smartptr.weakptr}{util.smartptr.weak.bad} + +% Deprecated features. +\movedxref{ccmplx}{depr.ccomplex.syn} +\deprxref{conversions.buffer} +\deprxref{conversions.string} +\deprxref{iterator.basic} +\deprxref{locale.stdcvt} +\deprxref{negators} +\deprxref{storage.iterator} +\deprxref{temporary.buffer} +\deprxref{uncaught} + +% :: -> . +\movedxref{istream::extractors}{istream.extractors} +\movedxref{string::append}{string.append} +\movedxref{string::assign}{string.assign} +\movedxref{string::compare}{string.compare} +\movedxref{string::copy}{string.copy} +\movedxref{string::erase}{string.erase} +\movedxref{string::find}{string.find} +\movedxref{string::find.first.not.of}{string.find.first.not.of} +\movedxref{string::find.first.of}{string.find.first.of} +\movedxref{string::find.last.not.of}{string.find.last.not.of} +\movedxref{string::find.last.of}{string.find.last.of} +\movedxref{string::insert}{string.insert} +\movedxref{string::op<}{string.op<} +\movedxref{string::op<=}{string.op<=} +\movedxref{string::op>}{string.op>} +\movedxref{string::op>=}{string.op>=} +\movedxref{string::op!=}{string.op!=} +\movedxref{string::op+}{string.op+} +\movedxref{string::op+=}{string.op+=} +\movedxref{string::operator==}{string.operator==} +\movedxref{string::replace}{string.replace} +\movedxref{string::rfind}{string.rfind} +\movedxref{string::substr}{string.substr} +\movedxref{string::swap}{string.swap} + +% Merged sections. +\movedxref{istreambuf.iterator::proxy}{istreambuf.iterator.proxy} +\movedxref{istreambuf.iterator::op*}{istreambuf.iterator.ops} +\movedxref{istreambuf.iterator::op++}{istreambuf.iterator.ops} +\movedxref{istreambuf.iterator::equal}{istreambuf.iterator.ops} +\movedxref{istreambuf.iterator::op==}{istreambuf.iterator.ops} +\movedxref{istreambuf.iterator::op!=}{istreambuf.iterator.ops}